OpenCores
URL https://opencores.org/ocsvn/hicovec/hicovec/trunk

Subversion Repositories hicovec

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/branches/avendor/debugger/pyparsing.py
0,0 → 1,2942
# module pyparsing.py
#
# Copyright (c) 2003-2006 Paul T. McGuire
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
#from __future__ import generators
 
__doc__ = \
"""
pyparsing module - Classes and methods to define and execute parsing grammars
 
The pyparsing module is an alternative approach to creating and executing simple grammars,
vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you
don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
provides a library of classes that you use to construct the grammar directly in Python.
 
Here is a program to parse "Hello, World!" (or any greeting of the form "<salutation>, <addressee>!")::
 
from pyparsing import Word, alphas
# define grammar of a greeting
greet = Word( alphas ) + "," + Word( alphas ) + "!"
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
 
The program outputs the following::
 
Hello, World! -> ['Hello', ',', 'World', '!']
 
The Python representation of the grammar is quite readable, owing to the self-explanatory
class names, and the use of '+', '|' and '^' operators.
 
The parsed results returned from parseString() can be accessed as a nested list, a dictionary, or an
object with named attributes.
 
The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
- extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.)
- quoted strings
- embedded comments
"""
__version__ = "1.4.4-Mod-HaraldManske"
__versionTime__ = "19 October 2006 23:11"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
 
 
#Modified by Harald Manske:
# - removed Deprication Warning of Upcase class
# - created Downcase class
 
import string
import copy,sys
import warnings
import re
import sre_constants
import xml.sax.saxutils
#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
 
def _ustr(obj):
"""Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
then < returns the unicode object | encodes it with the default encoding | ... >.
"""
try:
# If this works, then _ustr(obj) has the same behaviour as str(obj), so
# it won't break any existing code.
return str(obj)
except UnicodeEncodeError, e:
# The Python docs (http://docs.python.org/ref/customization.html#l2h-182)
# state that "The return value must be a string object". However, does a
# unicode object (being a subclass of basestring) count as a "string
# object"?
# If so, then return a unicode object:
return unicode(obj)
# Else encode it... but how? There are many choices... :)
# Replace unprintables with escape codes?
#return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors')
# Replace unprintables with question marks?
#return unicode(obj).encode(sys.getdefaultencoding(), 'replace')
# ...
 
def _str2dict(strg):
return dict( [(c,0) for c in strg] )
#~ return set( [c for c in strg] )
 
class _Constants(object):
pass
alphas = string.lowercase + string.uppercase
nums = string.digits
hexnums = nums + "ABCDEFabcdef"
alphanums = alphas + nums
 
class ParseBaseException(Exception):
"""base exception class for all parsing runtime exceptions"""
__slots__ = ( "loc","msg","pstr","parserElement" )
# Performance tuning: we construct a *lot* of these, so keep this
# constructor as small and fast as possible
def __init__( self, pstr, loc, msg, elem=None ):
self.loc = loc
self.msg = msg
self.pstr = pstr
self.parserElement = elem
 
def __getattr__( self, aname ):
"""supported attributes by name are:
- lineno - returns the line number of the exception text
- col - returns the column number of the exception text
- line - returns the line containing the exception text
"""
if( aname == "lineno" ):
return lineno( self.loc, self.pstr )
elif( aname in ("col", "column") ):
return col( self.loc, self.pstr )
elif( aname == "line" ):
return line( self.loc, self.pstr )
else:
raise AttributeError, aname
 
def __str__( self ):
return "%s (at char %d), (line:%d, col:%d)" % ( self.msg, self.loc, self.lineno, self.column )
def __repr__( self ):
return _ustr(self)
def markInputline( self, markerString = ">!<" ):
"""Extracts the exception line from the input string, and marks
the location of the exception with a special symbol.
"""
line_str = self.line
line_column = self.column - 1
if markerString:
line_str = "".join( [line_str[:line_column], markerString, line_str[line_column:]])
return line_str.strip()
 
class ParseException(ParseBaseException):
"""exception thrown when parse expressions don't match class"""
"""supported attributes by name are:
- lineno - returns the line number of the exception text
- col - returns the column number of the exception text
- line - returns the line containing the exception text
"""
pass
class ParseFatalException(ParseBaseException):
"""user-throwable exception thrown when inconsistent parse content
is found; stops all parsing immediately"""
pass
 
class ReparseException(ParseBaseException):
def __init_( self, newstring, restartLoc ):
self.newParseText = newstring
self.reparseLoc = restartLoc
 
 
class RecursiveGrammarException(Exception):
"""exception thrown by validate() if the grammar could be improperly recursive"""
def __init__( self, parseElementList ):
self.parseElementTrace = parseElementList
def __str__( self ):
return "RecursiveGrammarException: %s" % self.parseElementTrace
 
class ParseResults(object):
"""Structured parse results, to provide multiple means of access to the parsed data:
- as a list (len(results))
- by list index (results[0], results[1], etc.)
- by attribute (results.<resultsName>)
"""
__slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames" )
def __new__(cls, toklist, name=None, asList=True, modal=True ):
if isinstance(toklist, cls):
return toklist
retobj = object.__new__(cls)
retobj.__doinit = True
return retobj
# Performance tuning: we construct a *lot* of these, so keep this
# constructor as small and fast as possible
def __init__( self, toklist, name=None, asList=True, modal=True ):
if self.__doinit:
self.__doinit = False
self.__name = None
self.__parent = None
self.__accumNames = {}
if isinstance(toklist, list):
self.__toklist = toklist[:]
else:
self.__toklist = [toklist]
self.__tokdict = dict()
 
# this line is related to debugging the asXML bug
#~ asList = False
if name:
if not modal:
self.__accumNames[name] = 0
if isinstance(name,int):
name = _ustr(name) # will always return a str, but use _ustr for consistency
self.__name = name
if not toklist in (None,'',[]):
if isinstance(toklist,basestring):
toklist = [ toklist ]
if asList:
if isinstance(toklist,ParseResults):
self[name] = (toklist.copy(),-1)
else:
self[name] = (ParseResults(toklist[0]),-1)
self[name].__name = name
else:
try:
self[name] = toklist[0]
except (KeyError,TypeError):
self[name] = toklist
 
def __getitem__( self, i ):
if isinstance( i, (int,slice) ):
return self.__toklist[i]
else:
if i not in self.__accumNames:
return self.__tokdict[i][-1][0]
else:
return ParseResults([ v[0] for v in self.__tokdict[i] ])
 
def __setitem__( self, k, v ):
if isinstance(v,tuple):
self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
sub = v[0]
elif isinstance(k,int):
self.__toklist[k] = v
sub = v
else:
self.__tokdict[k] = self.__tokdict.get(k,list()) + [(v,0)]
sub = v
if isinstance(sub,ParseResults):
sub.__parent = self
def __delitem__( self, i ):
if isinstance(i,(int,slice)):
del self.__toklist[i]
else:
del self._tokdict[i]
 
def __contains__( self, k ):
return self.__tokdict.has_key(k)
def __len__( self ): return len( self.__toklist )
def __nonzero__( self ): return len( self.__toklist ) > 0
def __iter__( self ): return iter( self.__toklist )
def keys( self ):
"""Returns all named result keys."""
return self.__tokdict.keys()
def items( self ):
"""Returns all named result keys and values as a list of tuples."""
return [(k,self[k]) for k in self.__tokdict.keys()]
def values( self ):
"""Returns all named result values."""
return [ v[-1][0] for v in self.__tokdict.values() ]
 
def __getattr__( self, name ):
if name not in self.__slots__:
if self.__tokdict.has_key( name ):
if name not in self.__accumNames:
return self.__tokdict[name][-1][0]
else:
return ParseResults([ v[0] for v in self.__tokdict[name] ])
else:
return ""
return None
 
def __add__( self, other ):
ret = self.copy()
ret += other
return ret
def __iadd__( self, other ):
if other.__tokdict:
offset = len(self.__toklist)
addoffset = ( lambda a: (a<0 and offset) or (a+offset) )
otheritems = other.__tokdict.items()
otherdictitems = [(k,(v[0],addoffset(v[1])) ) for (k,vlist) in otheritems for v in vlist]
for k,v in otherdictitems:
self[k] = v
if isinstance(v[0],ParseResults):
v[0].__parent = self
self.__toklist += other.__toklist
self.__accumNames.update( other.__accumNames )
del other
return self
def __repr__( self ):
return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
 
def __str__( self ):
out = "["
sep = ""
for i in self.__toklist:
if isinstance(i, ParseResults):
out += sep + _ustr(i)
else:
out += sep + repr(i)
sep = ", "
out += "]"
return out
 
def _asStringList( self, sep='' ):
out = []
for item in self.__toklist:
if out and sep:
out.append(sep)
if isinstance( item, ParseResults ):
out += item._asStringList()
else:
out.append( _ustr(item) )
return out
 
def asList( self ):
"""Returns the parse results as a nested list of matching tokens, all converted to strings."""
out = []
for res in self.__toklist:
if isinstance(res,ParseResults):
out.append( res.asList() )
else:
out.append( res )
return out
 
def asDict( self ):
"""Returns the named parse results as dictionary."""
return dict( self.items() )
 
def copy( self ):
"""Returns a new copy of a ParseResults object."""
ret = ParseResults( self.__toklist )
ret.__tokdict = self.__tokdict.copy()
ret.__parent = self.__parent
ret.__accumNames.update( self.__accumNames )
ret.__name = self.__name
return ret
def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
"""Returns the parse results as XML. Tags are created for tokens and lists that have defined results names."""
nl = "\n"
out = []
namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items() for v in vlist ] )
nextLevelIndent = indent + " "
# collapse out indents if formatting is not desired
if not formatted:
indent = ""
nextLevelIndent = ""
nl = ""
selfTag = None
if doctag is not None:
selfTag = doctag
else:
if self.__name:
selfTag = self.__name
if not selfTag:
if namedItemsOnly:
return ""
else:
selfTag = "ITEM"
out += [ nl, indent, "<", selfTag, ">" ]
worklist = self.__toklist
for i,res in enumerate(worklist):
if isinstance(res,ParseResults):
if i in namedItems:
out += [ res.asXML(namedItems[i], namedItemsOnly and doctag is None, nextLevelIndent,formatted)]
else:
out += [ res.asXML(None, namedItemsOnly and doctag is None, nextLevelIndent,formatted)]
else:
# individual token, see if there is a name for it
resTag = None
if i in namedItems:
resTag = namedItems[i]
if not resTag:
if namedItemsOnly:
continue
else:
resTag = "ITEM"
xmlBodyText = xml.sax.saxutils.escape(_ustr(res))
out += [ nl, nextLevelIndent, "<", resTag, ">", xmlBodyText, "</", resTag, ">" ]
out += [ nl, indent, "</", selfTag, ">" ]
return "".join(out)
 
def __lookup(self,sub):
for k,vlist in self.__tokdict.items():
for v,loc in vlist:
if sub is v:
return k
return None
def getName(self):
"""Returns the results name for this token expression."""
if self.__name:
return self.__name
elif self.__parent:
par = self.__parent
if par:
return par.__lookup(self)
else:
return None
elif (len(self) == 1 and
len(self.__tokdict) == 1 and
self.__tokdict.values()[0][0][1] in (0,-1)):
return self.__tokdict.keys()[0]
else:
return None
def dump(self,indent='',depth=0):
"""Diagnostic method for listing out the contents of a ParseResults.
Accepts an optional indent argument so that this string can be embedded
in a nested display of other data."""
out = []
out.append( indent+str(self.asList()) )
keys = self.items()
keys.sort()
for k,v in keys:
if out:
out.append('\n')
out.append( "%s%s- %s: " % (indent,(' '*depth), k) )
if isinstance(v,ParseResults):
if v.keys():
#~ out.append('\n')
out.append( v.dump(indent,depth+1) )
#~ out.append('\n')
else:
out.append(str(v))
else:
out.append(str(v))
#~ out.append('\n')
return "".join(out)
def col (loc,strg):
"""Returns current column within a string, counting newlines as line separators.
The first column is number 1.
"""
return (loc<len(strg) and strg[loc] == '\n') and 1 or loc - strg.rfind("\n", 0, loc)
 
def lineno(loc,strg):
"""Returns current line number within a string, counting newlines as line separators.
The first line is number 1.
"""
return strg.count("\n",0,loc) + 1
 
def line( loc, strg ):
"""Returns the line of text containing loc within a string, counting newlines as line separators.
"""
lastCR = strg.rfind("\n", 0, loc)
nextCR = strg.find("\n", loc)
if nextCR > 0:
return strg[lastCR+1:nextCR]
else:
return strg[lastCR+1:]
 
def _defaultStartDebugAction( instring, loc, expr ):
print "Match",expr,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )
 
def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
print "Matched",expr,"->",toks.asList()
def _defaultExceptionDebugAction( instring, loc, expr, exc ):
print "Exception raised:", exc
 
def nullDebugAction(*args):
"""'Do-nothing' debug action, to suppress debugging output during parsing."""
pass
 
class ParserElement(object):
"""Abstract base level parser element class."""
DEFAULT_WHITE_CHARS = " \n\t\r"
def setDefaultWhitespaceChars( chars ):
"""Overrides the default whitespace chars
"""
ParserElement.DEFAULT_WHITE_CHARS = chars
setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars)
def __init__( self, savelist=False ):
self.parseAction = list()
self.failAction = None
#~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall
self.strRepr = None
self.resultsName = None
self.saveAsList = savelist
self.skipWhitespace = True
self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
self.copyDefaultWhiteChars = True
self.mayReturnEmpty = False
self.keepTabs = False
self.ignoreExprs = list()
self.debug = False
self.streamlined = False
self.mayIndexError = True
self.errmsg = ""
self.modalResults = True
self.debugActions = ( None, None, None )
self.re = None
 
def copy( self ):
"""Make a copy of this ParserElement. Useful for defining different parse actions
for the same parsing pattern, using copies of the original parse element."""
cpy = copy.copy( self )
cpy.parseAction = self.parseAction[:]
cpy.ignoreExprs = self.ignoreExprs[:]
if self.copyDefaultWhiteChars:
cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
return cpy
 
def setName( self, name ):
"""Define name for this expression, for use in debugging."""
self.name = name
self.errmsg = "Expected " + self.name
return self
 
def setResultsName( self, name, listAllMatches=False ):
"""Define name for referencing matching tokens as a nested attribute
of the returned parse results.
NOTE: this returns a *copy* of the original ParserElement object;
this is so that the client can define a basic element, such as an
integer, and reference it in multiple places with different names.
"""
newself = self.copy()
newself.resultsName = name
newself.modalResults = not listAllMatches
return newself
 
def normalizeParseActionArgs( f ):
"""Internal method used to decorate parse actions that take fewer than 3 arguments,
so that all parse actions can be called as f(s,l,t)."""
STAR_ARGS = 4
 
try:
restore = None
if isinstance(f,type):
restore = f
f = f.__init__
if f.func_code.co_flags & STAR_ARGS:
return f
numargs = f.func_code.co_argcount
if hasattr(f,"im_self"):
numargs -= 1
if restore:
f = restore
except AttributeError:
try:
# not a function, must be a callable object, get info from the
# im_func binding of its bound __call__ method
if f.__call__.im_func.func_code.co_flags & STAR_ARGS:
return f
numargs = f.__call__.im_func.func_code.co_argcount
if hasattr(f.__call__,"im_self"):
numargs -= 1
except AttributeError:
# not a bound method, get info directly from __call__ method
if f.__call__.func_code.co_flags & STAR_ARGS:
return f
numargs = f.__call__.func_code.co_argcount
if hasattr(f.__call__,"im_self"):
numargs -= 1
 
#~ print "adding function %s with %d args" % (f.func_name,numargs)
if numargs == 3:
return f
else:
if numargs == 2:
def tmp(s,l,t):
return f(l,t)
elif numargs == 1:
def tmp(s,l,t):
return f(t)
else: #~ numargs == 0:
def tmp(s,l,t):
return f()
return tmp
normalizeParseActionArgs = staticmethod(normalizeParseActionArgs)
def setParseAction( self, *fns ):
"""Define action to perform when successfully matching parse element definition.
Parse action fn is a callable method with 0-3 arguments, called as fn(s,loc,toks),
fn(loc,toks), fn(toks), or just fn(), where:
- s = the original string being parsed
- loc = the location of the matching substring
- toks = a list of the matched tokens, packaged as a ParseResults object
If the functions in fns modify the tokens, they can return them as the return
value from fn, and the modified list of tokens will replace the original.
Otherwise, fn does not need to return any value."""
self.parseAction = map(self.normalizeParseActionArgs, list(fns))
return self
 
def addParseAction( self, *fns ):
"""Add parse action to expression's list of parse actions. See setParseAction_."""
self.parseAction += map(self.normalizeParseActionArgs, list(fns))
return self
 
def setFailAction( self, fn ):
"""Define action to perform if parsing fails at this expression.
Fail acton fn is a callable function that takes the arguments
fn(s,loc,expr,err) where:
- s = string being parsed
- loc = location where expression match was attempted and failed
- expr = the parse expression that failed
- err = the exception thrown
The function returns no value. It may throw ParseFatalException
if it is desired to stop parsing immediately."""
self.failAction = fn
return self
def skipIgnorables( self, instring, loc ):
exprsFound = True
while exprsFound:
exprsFound = False
for e in self.ignoreExprs:
try:
while 1:
loc,dummy = e._parse( instring, loc )
exprsFound = True
except ParseException:
pass
return loc
 
def preParse( self, instring, loc ):
if self.ignoreExprs:
loc = self.skipIgnorables( instring, loc )
if self.skipWhitespace:
wt = self.whiteChars
instrlen = len(instring)
while loc < instrlen and instring[loc] in wt:
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
return loc, []
 
def postParse( self, instring, loc, tokenlist ):
return tokenlist
 
#~ @profile
def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
debugging = ( self.debug ) #and doActions )
 
if debugging or self.failAction:
#~ print "Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )
if (self.debugActions[0] ):
self.debugActions[0]( instring, loc, self )
if callPreParse:
preloc = self.preParse( instring, loc )
else:
preloc = loc
tokensStart = loc
try:
try:
loc,tokens = self.parseImpl( instring, preloc, doActions )
except IndexError:
raise ParseException( instring, len(instring), self.errmsg, self )
#~ except ReparseException, retryEx:
#~ pass
except ParseException, err:
#~ print "Exception raised:", err
if self.debugActions[2]:
self.debugActions[2]( instring, tokensStart, self, err )
if self.failAction:
self.failAction( instring, tokensStart, self, err )
raise
else:
if callPreParse:
preloc = self.preParse( instring, loc )
else:
preloc = loc
tokensStart = loc
if self.mayIndexError or loc >= len(instring):
try:
loc,tokens = self.parseImpl( instring, preloc, doActions )
except IndexError:
raise ParseException( instring, len(instring), self.errmsg, self )
else:
loc,tokens = self.parseImpl( instring, preloc, doActions )
tokens = self.postParse( instring, loc, tokens )
 
retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
if self.parseAction and doActions:
if debugging:
try:
for fn in self.parseAction:
tokens = fn( instring, tokensStart, retTokens )
if tokens is not None:
retTokens = ParseResults( tokens,
self.resultsName,
asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
modal=self.modalResults )
except ParseException, err:
#~ print "Exception raised in user parse action:", err
if (self.debugActions[2] ):
self.debugActions[2]( instring, tokensStart, self, err )
raise
else:
for fn in self.parseAction:
tokens = fn( instring, tokensStart, retTokens )
if tokens is not None:
retTokens = ParseResults( tokens,
self.resultsName,
asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
modal=self.modalResults )
 
if debugging:
#~ print "Matched",self,"->",retTokens.asList()
if (self.debugActions[1] ):
self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
 
return loc, retTokens
 
def tryParse( self, instring, loc ):
return self._parse( instring, loc, doActions=False )[0]
# this method gets repeatedly called during backtracking with the same arguments -
# we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
if doActions and self.parseAction:
return self._parseNoCache( instring, loc, doActions, callPreParse )
lookup = (self,instring,loc,callPreParse)
if lookup in ParserElement._exprArgCache:
value = ParserElement._exprArgCache[ lookup ]
if isinstance(value,Exception):
if isinstance(value,ParseBaseException):
value.loc = loc
raise value
return value
else:
try:
ParserElement._exprArgCache[ lookup ] = \
value = self._parseNoCache( instring, loc, doActions, callPreParse )
return value
except ParseBaseException, pe:
ParserElement._exprArgCache[ lookup ] = pe
raise
 
_parse = _parseNoCache
 
# argument cache for optimizing repeated calls when backtracking through recursive expressions
_exprArgCache = {}
def resetCache():
ParserElement._exprArgCache.clear()
resetCache = staticmethod(resetCache)
_packratEnabled = False
def enablePackrat():
"""Enables "packrat" parsing, which adds memoizing to the parsing logic.
Repeated parse attempts at the same string location (which happens
often in many complex grammars) can immediately return a cached value,
instead of re-executing parsing/validating code. Memoizing is done of
both valid results and parsing exceptions.
This speedup may break existing programs that use parse actions that
have side-effects. For this reason, packrat parsing is disabled when
you first import pyparsing. To activate the packrat feature, your
program must call the class method ParserElement.enablePackrat(). If
your program uses psyco to "compile as you go", you must call
enablePackrat before calling psyco.full(). If you do not do this,
Python will crash. For best results, call enablePackrat() immediately
after importing pyparsing.
"""
if not ParserElement._packratEnabled:
ParserElement._packratEnabled = True
ParserElement._parse = ParserElement._parseCache
enablePackrat = staticmethod(enablePackrat)
 
def parseString( self, instring ):
"""Execute the parse expression with the given string.
This is the main interface to the client code, once the complete
expression has been built.
"""
ParserElement.resetCache()
if not self.streamlined:
self.streamline()
#~ self.saveAsList = True
for e in self.ignoreExprs:
e.streamline()
if self.keepTabs:
loc, tokens = self._parse( instring, 0 )
else:
loc, tokens = self._parse( instring.expandtabs(), 0 )
return tokens
 
def scanString( self, instring, maxMatches=sys.maxint ):
"""Scan the input string for expression matches. Each match will return the
matching tokens, start location, and end location. May be called with optional
maxMatches argument, to clip scanning after 'n' matches are found."""
if not self.streamlined:
self.streamline()
for e in self.ignoreExprs:
e.streamline()
if not self.keepTabs:
instring = instring.expandtabs()
instrlen = len(instring)
loc = 0
preparseFn = self.preParse
parseFn = self._parse
ParserElement.resetCache()
matches = 0
while loc <= instrlen and matches < maxMatches:
try:
preloc = preparseFn( instring, loc )
nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
except ParseException:
loc = preloc+1
else:
matches += 1
yield tokens, preloc, nextLoc
loc = nextLoc
def transformString( self, instring ):
"""Extension to scanString, to modify matching text with modified tokens that may
be returned from a parse action. To use transformString, define a grammar and
attach a parse action to it that modifies the returned token list.
Invoking transformString() on a target string will then scan for matches,
and replace the matched text patterns according to the logic in the parse
action. transformString() returns the resulting transformed string."""
out = []
lastE = 0
# force preservation of <TAB>s, to minimize unwanted transformation of string, and to
# keep string locs straight between transformString and scanString
self.keepTabs = True
for t,s,e in self.scanString( instring ):
out.append( instring[lastE:s] )
if t:
if isinstance(t,ParseResults):
out += t.asList()
elif isinstance(t,list):
out += t
else:
out.append(t)
lastE = e
out.append(instring[lastE:])
return "".join(out)
 
def searchString( self, instring, maxMatches=sys.maxint ):
"""Another extension to scanString, simplifying the access to the tokens found
to match the given parse expression. May be called with optional
maxMatches argument, to clip searching after 'n' matches are found.
"""
return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
def __add__(self, other ):
"""Implementation of + operator - returns And"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return And( [ self, other ] )
 
def __radd__(self, other ):
"""Implementation of += operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other + self
 
def __or__(self, other ):
"""Implementation of | operator - returns MatchFirst"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return MatchFirst( [ self, other ] )
 
def __ror__(self, other ):
"""Implementation of |= operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other | self
 
def __xor__(self, other ):
"""Implementation of ^ operator - returns Or"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return Or( [ self, other ] )
 
def __rxor__(self, other ):
"""Implementation of ^= operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other ^ self
 
def __and__(self, other ):
"""Implementation of & operator - returns Each"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return Each( [ self, other ] )
 
def __rand__(self, other ):
"""Implementation of right-& operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other & self
 
def __invert__( self ):
"""Implementation of ~ operator - returns NotAny"""
return NotAny( self )
 
def suppress( self ):
"""Suppresses the output of this ParserElement; useful to keep punctuation from
cluttering up returned output.
"""
return Suppress( self )
 
def leaveWhitespace( self ):
"""Disables the skipping of whitespace before matching the characters in the
ParserElement's defined pattern. This is normally only used internally by
the pyparsing module, but may be needed in some whitespace-sensitive grammars.
"""
self.skipWhitespace = False
return self
 
def setWhitespaceChars( self, chars ):
"""Overrides the default whitespace chars
"""
self.skipWhitespace = True
self.whiteChars = chars
self.copyDefaultWhiteChars = False
return self
def parseWithTabs( self ):
"""Overrides default behavior to expand <TAB>s to spaces before parsing the input string.
Must be called before parseString when the input grammar contains elements that
match <TAB> characters."""
self.keepTabs = True
return self
def ignore( self, other ):
"""Define expression to be ignored (e.g., comments) while doing pattern
matching; may be called repeatedly, to define multiple comment or other
ignorable patterns.
"""
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
self.ignoreExprs.append( other )
else:
self.ignoreExprs.append( Suppress( other ) )
return self
 
def setDebugActions( self, startAction, successAction, exceptionAction ):
"""Enable display of debugging messages while doing pattern matching."""
self.debugActions = (startAction or _defaultStartDebugAction,
successAction or _defaultSuccessDebugAction,
exceptionAction or _defaultExceptionDebugAction)
self.debug = True
return self
 
def setDebug( self, flag=True ):
"""Enable display of debugging messages while doing pattern matching."""
if flag:
self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
else:
self.debug = False
return self
 
def __str__( self ):
return self.name
 
def __repr__( self ):
return _ustr(self)
def streamline( self ):
self.streamlined = True
self.strRepr = None
return self
def checkRecursion( self, parseElementList ):
pass
def validate( self, validateTrace=[] ):
"""Check defined expressions for valid structure, check for infinite recursive definitions."""
self.checkRecursion( [] )
 
def parseFile( self, file_or_filename ):
"""Execute the parse expression on the given file or filename.
If a filename is specified (instead of a file object),
the entire file is opened, read, and closed before parsing.
"""
try:
file_contents = file_or_filename.read()
except AttributeError:
f = open(file_or_filename, "rb")
file_contents = f.read()
f.close()
return self.parseString(file_contents)
 
 
class Token(ParserElement):
"""Abstract ParserElement subclass, for defining atomic matching patterns."""
def __init__( self ):
super(Token,self).__init__( savelist=False )
self.myException = ParseException("",0,"",self)
 
def setName(self, name):
s = super(Token,self).setName(name)
self.errmsg = "Expected " + self.name
s.myException.msg = self.errmsg
return s
 
 
class Empty(Token):
"""An empty token, will always match."""
def __init__( self ):
super(Empty,self).__init__()
self.name = "Empty"
self.mayReturnEmpty = True
self.mayIndexError = False
 
 
class NoMatch(Token):
"""A token that will never match."""
def __init__( self ):
super(NoMatch,self).__init__()
self.name = "NoMatch"
self.mayReturnEmpty = True
self.mayIndexError = False
self.errmsg = "Unmatchable token"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
 
class Literal(Token):
"""Token to exactly match a specified string."""
def __init__( self, matchString ):
super(Literal,self).__init__()
self.match = matchString
self.matchLen = len(matchString)
try:
self.firstMatchChar = matchString[0]
except IndexError:
warnings.warn("null string passed to Literal; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.__class__ = Empty
self.name = '"%s"' % self.match
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = False
self.myException.msg = self.errmsg
self.mayIndexError = False
 
# Performance tuning: this routine gets called a *lot*
# if this is a single character match string and the first character matches,
# short-circuit as quickly as possible, and avoid calling startswith
#~ @profile
def parseImpl( self, instring, loc, doActions=True ):
if (instring[loc] == self.firstMatchChar and
(self.matchLen==1 or instring.startswith(self.match,loc)) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Keyword(Token):
"""Token to exactly match a specified string as a keyword, that is, it must be
immediately followed by a non-keyword character. Compare with Literal::
Literal("if") will match the leading 'if' in 'ifAndOnlyIf'.
Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)'
Accepts two optional constructor arguments in addition to the keyword string:
identChars is a string of characters that would be valid identifier characters,
defaulting to all alphanumerics + "_" and "$"; caseless allows case-insensitive
matching, default is False.
"""
DEFAULT_KEYWORD_CHARS = alphanums+"_$"
def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ):
super(Keyword,self).__init__()
self.match = matchString
self.matchLen = len(matchString)
try:
self.firstMatchChar = matchString[0]
except IndexError:
warnings.warn("null string passed to Keyword; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.name = '"%s"' % self.match
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = False
self.myException.msg = self.errmsg
self.mayIndexError = False
self.caseless = caseless
if caseless:
self.caselessmatch = matchString.upper()
identChars = identChars.upper()
self.identChars = _str2dict(identChars)
 
def parseImpl( self, instring, loc, doActions=True ):
if self.caseless:
if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
(loc == 0 or instring[loc-1].upper() not in self.identChars) ):
return loc+self.matchLen, self.match
else:
if (instring[loc] == self.firstMatchChar and
(self.matchLen==1 or instring.startswith(self.match,loc)) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
(loc == 0 or instring[loc-1] not in self.identChars) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
def copy(self):
c = super(Keyword,self).copy()
c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
return c
def setDefaultKeywordChars( chars ):
"""Overrides the default Keyword chars
"""
Keyword.DEFAULT_KEYWORD_CHARS = chars
setDefaultKeywordChars = staticmethod(setDefaultKeywordChars)
 
 
class CaselessLiteral(Literal):
"""Token to match a specified string, ignoring case of letters.
Note: the matched results will always be in the case of the given
match string, NOT the case of the input text.
"""
def __init__( self, matchString ):
super(CaselessLiteral,self).__init__( matchString.upper() )
# Preserve the defining literal.
self.returnString = matchString
self.name = "'%s'" % self.returnString
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
 
def parseImpl( self, instring, loc, doActions=True ):
if instring[ loc:loc+self.matchLen ].upper() == self.match:
return loc+self.matchLen, self.returnString
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class CaselessKeyword(Keyword):
def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ):
super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
 
def parseImpl( self, instring, loc, doActions=True ):
if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Word(Token):
"""Token for matching words composed of allowed character sets.
Defined with string containing all allowed initial characters,
an optional string containing allowed body characters (if omitted,
defaults to the initial character set), and an optional minimum,
maximum, and/or exact length.
"""
def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0 ):
super(Word,self).__init__()
self.initCharsOrig = initChars
self.initChars = _str2dict(initChars)
if bodyChars :
self.bodyCharsOrig = bodyChars
self.bodyChars = _str2dict(bodyChars)
else:
self.bodyCharsOrig = initChars
self.bodyChars = _str2dict(initChars)
self.maxSpecified = max > 0
 
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
if self.bodyCharsOrig == self.initCharsOrig:
self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
elif len(self.bodyCharsOrig) == 1:
self.reString = "%s[%s]*" % \
(re.escape(self.initCharsOrig),
_escapeRegexRangeChars(self.bodyCharsOrig),)
else:
self.reString = "[%s][%s]*" % \
(_escapeRegexRangeChars(self.initCharsOrig),
_escapeRegexRangeChars(self.bodyCharsOrig),)
try:
self.re = re.compile( self.reString )
except:
self.re = None
def parseImpl( self, instring, loc, doActions=True ):
if self.re:
result = self.re.match(instring,loc)
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
return loc,result.group()
if not(instring[ loc ] in self.initChars):
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
instrlen = len(instring)
bodychars = self.bodyChars
maxloc = start + self.maxLen
maxloc = min( maxloc, instrlen )
while loc < maxloc and instring[loc] in bodychars:
loc += 1
throwException = False
if loc - start < self.minLen:
throwException = True
if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
throwException = True
 
if throwException:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
def __str__( self ):
try:
return super(Word,self).__str__()
except:
pass
 
if self.strRepr is None:
def charsAsStr(s):
if len(s)>4:
return s[:4]+"..."
else:
return s
if ( self.initCharsOrig != self.bodyCharsOrig ):
self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
else:
self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
 
return self.strRepr
 
 
class Regex(Token):
"""Token for matching strings that match a given regular expression.
Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
"""
def __init__( self, pattern, flags=0):
"""The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags."""
super(Regex,self).__init__()
if len(pattern) == 0:
warnings.warn("null string passed to Regex; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.pattern = pattern
self.flags = flags
try:
self.re = re.compile(self.pattern, self.flags)
self.reString = self.pattern
except sre_constants.error,e:
warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
SyntaxWarning, stacklevel=2)
raise
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
result = self.re.match(instring,loc)
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
d = result.groupdict()
ret = ParseResults(result.group())
if d:
for k in d.keys():
ret[k] = d[k]
return loc,ret
def __str__( self ):
try:
return super(Regex,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "Re:(%s)" % repr(self.pattern)
return self.strRepr
 
 
class QuotedString(Token):
"""Token for matching strings that are delimited by quoting characters.
"""
def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None):
"""
Defined with the following parameters:
- quoteChar - string of one or more characters defining the quote delimiting string
- escChar - character to escape quotes, typically backslash (default=None)
- escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
- multiline - boolean indicating whether quotes can span multiple lines (default=False)
- unquoteResults - boolean indicating whether the matched text should be unquoted (default=True)
- endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar)
"""
super(QuotedString,self).__init__()
# remove white space from quote chars - wont work anyway
quoteChar = quoteChar.strip()
if len(quoteChar) == 0:
warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
raise SyntaxError()
if endQuoteChar is None:
endQuoteChar = quoteChar
else:
endQuoteChar = endQuoteChar.strip()
if len(endQuoteChar) == 0:
warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
raise SyntaxError()
self.quoteChar = quoteChar
self.quoteCharLen = len(quoteChar)
self.firstQuoteChar = quoteChar[0]
self.endQuoteChar = endQuoteChar
self.endQuoteCharLen = len(endQuoteChar)
self.escChar = escChar
self.escQuote = escQuote
self.unquoteResults = unquoteResults
if multiline:
self.flags = re.MULTILINE | re.DOTALL
self.pattern = r'%s(?:[^%s%s]' % \
( re.escape(self.quoteChar),
_escapeRegexRangeChars(self.endQuoteChar[0]),
(escChar is not None and _escapeRegexRangeChars(escChar) or '') )
else:
self.flags = 0
self.pattern = r'%s(?:[^%s\n\r%s]' % \
( re.escape(self.quoteChar),
_escapeRegexRangeChars(self.endQuoteChar[0]),
(escChar is not None and _escapeRegexRangeChars(escChar) or '') )
if len(self.endQuoteChar) > 1:
self.pattern += (
'|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
_escapeRegexRangeChars(self.endQuoteChar[i]))
for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')'
)
if escQuote:
self.pattern += (r'|(?:%s)' % re.escape(escQuote))
if escChar:
self.pattern += (r'|(?:%s.)' % re.escape(escChar))
self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
try:
self.re = re.compile(self.pattern, self.flags)
self.reString = self.pattern
except sre_constants.error,e:
warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
SyntaxWarning, stacklevel=2)
raise
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
ret = result.group()
print ret
if self.unquoteResults:
# strip off quotes
ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
if isinstance(ret,basestring):
# replace escaped characters
if self.escChar:
ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
 
# replace escaped quotes
if self.escQuote:
ret = ret.replace(self.escQuote, self.endQuoteChar)
 
return loc, ret
def __str__( self ):
try:
return super(QuotedString,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
return self.strRepr
 
 
class CharsNotIn(Token):
"""Token for matching words composed of characters *not* in a given set.
Defined with string containing all disallowed characters, and an optional
minimum, maximum, and/or exact length.
"""
def __init__( self, notChars, min=1, max=0, exact=0 ):
super(CharsNotIn,self).__init__()
self.skipWhitespace = False
self.notChars = notChars
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = ( self.minLen == 0 )
self.myException.msg = self.errmsg
self.mayIndexError = False
 
def parseImpl( self, instring, loc, doActions=True ):
if instring[loc] in self.notChars:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
notchars = self.notChars
maxlen = min( start+self.maxLen, len(instring) )
while loc < maxlen and \
(instring[loc] not in notchars):
loc += 1
 
if loc - start < self.minLen:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
def __str__( self ):
try:
return super(CharsNotIn, self).__str__()
except:
pass
 
if self.strRepr is None:
if len(self.notChars) > 4:
self.strRepr = "!W:(%s...)" % self.notChars[:4]
else:
self.strRepr = "!W:(%s)" % self.notChars
return self.strRepr
 
class White(Token):
"""Special matching class for matching whitespace. Normally, whitespace is ignored
by pyparsing grammars. This class is included when some whitespace structures
are significant. Define with a string containing the whitespace characters to be
matched; default is " \\t\\n". Also takes optional min, max, and exact arguments,
as defined for the Word class."""
whiteStrs = {
" " : "<SPC>",
"\t": "<TAB>",
"\n": "<LF>",
"\r": "<CR>",
"\f": "<FF>",
}
def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
super(White,self).__init__()
self.matchWhite = ws
self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) )
#~ self.leaveWhitespace()
self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite]))
self.mayReturnEmpty = True
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
 
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
def parseImpl( self, instring, loc, doActions=True ):
if not(instring[ loc ] in self.matchWhite):
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
maxloc = start + self.maxLen
maxloc = min( maxloc, len(instring) )
while loc < maxloc and instring[loc] in self.matchWhite:
loc += 1
 
if loc - start < self.minLen:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
 
class PositionToken(Token):
def __init__( self ):
super(PositionToken,self).__init__()
self.name=self.__class__.__name__
self.mayReturnEmpty = True
self.mayIndexError = False
 
class GoToColumn(PositionToken):
"""Token to advance to a specific column of input text; useful for tabular report scraping."""
def __init__( self, colno ):
super(GoToColumn,self).__init__()
self.col = colno
 
def preParse( self, instring, loc ):
if col(loc,instring) != self.col:
instrlen = len(instring)
if self.ignoreExprs:
loc = self.skipIgnorables( instring, loc )
while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
thiscol = col( loc, instring )
if thiscol > self.col:
raise ParseException( instring, loc, "Text not in expected column", self )
newloc = loc + self.col - thiscol
ret = instring[ loc: newloc ]
return newloc, ret
 
class LineStart(PositionToken):
"""Matches if current position is at the beginning of a line within the parse string"""
def __init__( self ):
super(LineStart,self).__init__()
self.setWhitespaceChars( " \t" )
self.errmsg = "Expected start of line"
self.myException.msg = self.errmsg
 
def preParse( self, instring, loc ):
preloc = super(LineStart,self).preParse(instring,loc)
if instring[preloc] == "\n":
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
if not( loc==0 or ( loc<len(instring) and instring[loc-1] == "\n" ) ): #col(loc, instring) != 1:
#~ raise ParseException( instring, loc, "Expected start of line" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
class LineEnd(PositionToken):
"""Matches if current position is at the end of a line within the parse string"""
def __init__( self ):
super(LineEnd,self).__init__()
self.setWhitespaceChars( " \t" )
self.errmsg = "Expected end of line"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc<len(instring):
if instring[loc] == "\n":
return loc+1, "\n"
else:
#~ raise ParseException( instring, loc, "Expected end of line" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
elif loc == len(instring):
return loc+1, []
else:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class StringStart(PositionToken):
"""Matches if current position is at the beginning of the parse string"""
def __init__( self ):
super(StringStart,self).__init__()
self.errmsg = "Expected start of text"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc != 0:
# see if entire string up to here is just whitespace and ignoreables
if loc != self.preParse( instring, 0 ):
#~ raise ParseException( instring, loc, "Expected start of text" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
class StringEnd(PositionToken):
"""Matches if current position is at the end of the parse string"""
def __init__( self ):
super(StringEnd,self).__init__()
self.errmsg = "Expected end of text"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc < len(instring):
#~ raise ParseException( instring, loc, "Expected end of text" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
elif loc == len(instring):
return loc+1, []
else:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
 
class ParseExpression(ParserElement):
"""Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
def __init__( self, exprs, savelist = False ):
super(ParseExpression,self).__init__(savelist)
if isinstance( exprs, list ):
self.exprs = exprs
elif isinstance( exprs, basestring ):
self.exprs = [ Literal( exprs ) ]
else:
self.exprs = [ exprs ]
 
def __getitem__( self, i ):
return self.exprs[i]
 
def append( self, other ):
self.exprs.append( other )
self.strRepr = None
return self
 
def leaveWhitespace( self ):
"""Extends leaveWhitespace defined in base class, and also invokes leaveWhitespace on
all contained expressions."""
self.skipWhitespace = False
self.exprs = [ e.copy() for e in self.exprs ]
for e in self.exprs:
e.leaveWhitespace()
return self
 
def ignore( self, other ):
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
super( ParseExpression, self).ignore( other )
for e in self.exprs:
e.ignore( self.ignoreExprs[-1] )
else:
super( ParseExpression, self).ignore( other )
for e in self.exprs:
e.ignore( self.ignoreExprs[-1] )
return self
 
def __str__( self ):
try:
return super(ParseExpression,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
return self.strRepr
 
def streamline( self ):
super(ParseExpression,self).streamline()
 
for e in self.exprs:
e.streamline()
 
# collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
# but only if there are no parse actions or resultsNames on the nested And's
# (likewise for Or's and MatchFirst's)
if ( len(self.exprs) == 2 ):
other = self.exprs[0]
if ( isinstance( other, self.__class__ ) and
not(other.parseAction) and
other.resultsName is None and
not other.debug ):
self.exprs = other.exprs[:] + [ self.exprs[1] ]
self.strRepr = None
self.mayReturnEmpty |= other.mayReturnEmpty
self.mayIndexError |= other.mayIndexError
 
other = self.exprs[-1]
if ( isinstance( other, self.__class__ ) and
not(other.parseAction) and
other.resultsName is None and
not other.debug ):
self.exprs = self.exprs[:-1] + other.exprs[:]
self.strRepr = None
self.mayReturnEmpty |= other.mayReturnEmpty
self.mayIndexError |= other.mayIndexError
 
return self
 
def setResultsName( self, name, listAllMatches=False ):
ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
return ret
def validate( self, validateTrace=[] ):
tmp = validateTrace[:]+[self]
for e in self.exprs:
e.validate(tmp)
self.checkRecursion( [] )
 
class And(ParseExpression):
"""Requires all given ParseExpressions to be found in the given order.
Expressions may be separated by whitespace.
May be constructed using the '+' operator.
"""
def __init__( self, exprs, savelist = True ):
super(And,self).__init__(exprs, savelist)
self.mayReturnEmpty = True
for e in self.exprs:
if not e.mayReturnEmpty:
self.mayReturnEmpty = False
break
self.setWhitespaceChars( exprs[0].whiteChars )
self.skipWhitespace = exprs[0].skipWhitespace
 
def parseImpl( self, instring, loc, doActions=True ):
loc, resultlist = self.exprs[0]._parse( instring, loc, doActions )
for e in self.exprs[1:]:
loc, exprtokens = e._parse( instring, loc, doActions )
if exprtokens or exprtokens.keys():
resultlist += exprtokens
return loc, resultlist
 
def __iadd__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #And( [ self, other ] )
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
if not e.mayReturnEmpty:
break
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
 
class Or(ParseExpression):
"""Requires that at least one ParseExpression is found.
If two expressions match, the expression that matches the longest string will be used.
May be constructed using the '^' operator.
"""
def __init__( self, exprs, savelist = False ):
super(Or,self).__init__(exprs, savelist)
self.mayReturnEmpty = False
for e in self.exprs:
if e.mayReturnEmpty:
self.mayReturnEmpty = True
break
def parseImpl( self, instring, loc, doActions=True ):
maxExcLoc = -1
maxMatchLoc = -1
for e in self.exprs:
try:
loc2 = e.tryParse( instring, loc )
except ParseException, err:
if err.loc > maxExcLoc:
maxException = err
maxExcLoc = err.loc
except IndexError, err:
if len(instring) > maxExcLoc:
maxException = ParseException(instring,len(instring),e.errmsg,self)
maxExcLoc = len(instring)
else:
if loc2 > maxMatchLoc:
maxMatchLoc = loc2
maxMatchExp = e
if maxMatchLoc < 0:
if self.exprs:
raise maxException
else:
raise ParseException(instring, loc, "no defined alternatives to match", self)
 
return maxMatchExp._parse( instring, loc, doActions )
 
def __ixor__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #Or( [ self, other ] )
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
 
class MatchFirst(ParseExpression):
"""Requires that at least one ParseExpression is found.
If two expressions match, the first one listed is the one that will match.
May be constructed using the '|' operator.
"""
def __init__( self, exprs, savelist = False ):
super(MatchFirst,self).__init__(exprs, savelist)
if exprs:
self.mayReturnEmpty = False
for e in self.exprs:
if e.mayReturnEmpty:
self.mayReturnEmpty = True
break
else:
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
maxExcLoc = -1
for e in self.exprs:
try:
ret = e._parse( instring, loc, doActions )
return ret
except ParseException, err:
if err.loc > maxExcLoc:
maxException = err
maxExcLoc = err.loc
except IndexError, err:
if len(instring) > maxExcLoc:
maxException = ParseException(instring,len(instring),e.errmsg,self)
maxExcLoc = len(instring)
 
# only got here if no expression matched, raise exception for match that made it the furthest
else:
if self.exprs:
raise maxException
else:
raise ParseException(instring, loc, "no defined alternatives to match", self)
 
def __ior__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #MatchFirst( [ self, other ] )
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
class Each(ParseExpression):
"""Requires all given ParseExpressions to be found, but in any order.
Expressions may be separated by whitespace.
May be constructed using the '&' operator.
"""
def __init__( self, exprs, savelist = True ):
super(Each,self).__init__(exprs, savelist)
self.mayReturnEmpty = True
for e in self.exprs:
if not e.mayReturnEmpty:
self.mayReturnEmpty = False
break
self.skipWhitespace = True
self.optionals = [ e.expr for e in exprs if isinstance(e,Optional) ]
self.multioptionals = [ e.expr for e in exprs if isinstance(e,ZeroOrMore) ]
self.multirequired = [ e.expr for e in exprs if isinstance(e,OneOrMore) ]
self.required = [ e for e in exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
self.required += self.multirequired
 
def parseImpl( self, instring, loc, doActions=True ):
tmpLoc = loc
tmpReqd = self.required[:]
tmpOpt = self.optionals[:]
matchOrder = []
 
keepMatching = True
while keepMatching:
tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
failed = []
for e in tmpExprs:
try:
tmpLoc = e.tryParse( instring, tmpLoc )
except ParseException:
failed.append(e)
else:
matchOrder.append(e)
if e in tmpReqd:
tmpReqd.remove(e)
elif e in tmpOpt:
tmpOpt.remove(e)
if len(failed) == len(tmpExprs):
keepMatching = False
if tmpReqd:
missing = ", ".join( [ _ustr(e) for e in tmpReqd ] )
raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
 
resultlist = []
for e in matchOrder:
loc,results = e._parse(instring,loc,doActions)
resultlist.append(results)
finalResults = ParseResults([])
for r in resultlist:
dups = {}
for k in r.keys():
if k in finalResults.keys():
tmp = ParseResults(finalResults[k])
tmp += ParseResults(r[k])
dups[k] = tmp
finalResults += ParseResults(r)
for k,v in dups.items():
finalResults[k] = v
return loc, finalResults
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
 
class ParseElementEnhance(ParserElement):
"""Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
def __init__( self, expr, savelist=False ):
super(ParseElementEnhance,self).__init__(savelist)
if isinstance( expr, basestring ):
expr = Literal(expr)
self.expr = expr
self.strRepr = None
if expr is not None:
self.mayIndexError = expr.mayIndexError
self.setWhitespaceChars( expr.whiteChars )
self.skipWhitespace = expr.skipWhitespace
self.saveAsList = expr.saveAsList
def parseImpl( self, instring, loc, doActions=True ):
if self.expr is not None:
return self.expr._parse( instring, loc, doActions )
else:
raise ParseException("",loc,self.errmsg,self)
def leaveWhitespace( self ):
self.skipWhitespace = False
self.expr = self.expr.copy()
if self.expr is not None:
self.expr.leaveWhitespace()
return self
 
def ignore( self, other ):
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
super( ParseElementEnhance, self).ignore( other )
if self.expr is not None:
self.expr.ignore( self.ignoreExprs[-1] )
else:
super( ParseElementEnhance, self).ignore( other )
if self.expr is not None:
self.expr.ignore( self.ignoreExprs[-1] )
return self
 
def streamline( self ):
super(ParseElementEnhance,self).streamline()
if self.expr is not None:
self.expr.streamline()
return self
 
def checkRecursion( self, parseElementList ):
if self in parseElementList:
raise RecursiveGrammarException( parseElementList+[self] )
subRecCheckList = parseElementList[:] + [ self ]
if self.expr is not None:
self.expr.checkRecursion( subRecCheckList )
def validate( self, validateTrace=[] ):
tmp = validateTrace[:]+[self]
if self.expr is not None:
self.expr.validate(tmp)
self.checkRecursion( [] )
def __str__( self ):
try:
return super(ParseElementEnhance,self).__str__()
except:
pass
if self.strRepr is None and self.expr is not None:
self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
return self.strRepr
 
 
class FollowedBy(ParseElementEnhance):
"""Lookahead matching of the given parse expression. FollowedBy
does *not* advance the parsing position within the input string, it only
verifies that the specified parse expression matches at the current
position. FollowedBy always returns a null token list."""
def __init__( self, expr ):
super(FollowedBy,self).__init__(expr)
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
self.expr.tryParse( instring, loc )
return loc, []
 
 
class NotAny(ParseElementEnhance):
"""Lookahead to disallow matching with the given parse expression. NotAny
does *not* advance the parsing position within the input string, it only
verifies that the specified parse expression does *not* match at the current
position. Also, NotAny does *not* skip over leading whitespace. NotAny
always returns a null token list. May be constructed using the '~' operator."""
def __init__( self, expr ):
super(NotAny,self).__init__(expr)
#~ self.leaveWhitespace()
self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
self.mayReturnEmpty = True
self.errmsg = "Found unwanted token, "+_ustr(self.expr)
self.myException = ParseException("",0,self.errmsg,self)
def parseImpl( self, instring, loc, doActions=True ):
try:
self.expr.tryParse( instring, loc )
except (ParseException,IndexError):
pass
else:
#~ raise ParseException(instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "~{" + _ustr(self.expr) + "}"
return self.strRepr
 
 
class ZeroOrMore(ParseElementEnhance):
"""Optional repetition of zero or more of the given expression."""
def __init__( self, expr ):
super(ZeroOrMore,self).__init__(expr)
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
tokens = []
try:
loc, tokens = self.expr._parse( instring, loc, doActions )
hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
while 1:
if hasIgnoreExprs:
preloc = self.skipIgnorables( instring, loc )
else:
preloc = loc
loc, tmptokens = self.expr._parse( instring, preloc, doActions )
if tmptokens or tmptokens.keys():
tokens += tmptokens
except (ParseException,IndexError):
pass
 
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "[" + _ustr(self.expr) + "]..."
return self.strRepr
def setResultsName( self, name, listAllMatches=False ):
ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches)
ret.saveAsList = True
return ret
 
class OneOrMore(ParseElementEnhance):
"""Repetition of one or more of the given expression."""
def parseImpl( self, instring, loc, doActions=True ):
# must be at least one
loc, tokens = self.expr._parse( instring, loc, doActions )
try:
hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
while 1:
if hasIgnoreExprs:
preloc = self.skipIgnorables( instring, loc )
else:
preloc = loc
loc, tmptokens = self.expr._parse( instring, preloc, doActions )
if tmptokens or tmptokens.keys():
tokens += tmptokens
except (ParseException,IndexError):
pass
 
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + _ustr(self.expr) + "}..."
return self.strRepr
def setResultsName( self, name, listAllMatches=False ):
ret = super(OneOrMore,self).setResultsName(name,listAllMatches)
ret.saveAsList = True
return ret
 
class _NullToken(object):
def __bool__(self):
return False
def __str__(self):
return ""
 
_optionalNotMatched = _NullToken()
class Optional(ParseElementEnhance):
"""Optional matching of the given expression.
A default return string can also be specified, if the optional expression
is not found.
"""
def __init__( self, exprs, default=_optionalNotMatched ):
super(Optional,self).__init__( exprs, savelist=False )
self.defaultValue = default
self.mayReturnEmpty = True
 
def parseImpl( self, instring, loc, doActions=True ):
try:
loc, tokens = self.expr._parse( instring, loc, doActions )
except (ParseException,IndexError):
if self.defaultValue is not _optionalNotMatched:
tokens = [ self.defaultValue ]
else:
tokens = []
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "[" + _ustr(self.expr) + "]"
return self.strRepr
 
 
class SkipTo(ParseElementEnhance):
"""Token for skipping over all undefined text until the matched expression is found.
If include is set to true, the matched expression is also consumed. The ignore
argument is used to define grammars (typically quoted strings and comments) that
might contain false matches.
"""
def __init__( self, other, include=False, ignore=None ):
super( SkipTo, self ).__init__( other )
if ignore is not None:
self.expr = self.expr.copy()
self.expr.ignore(ignore)
self.mayReturnEmpty = True
self.mayIndexError = False
self.includeMatch = include
self.asList = False
self.errmsg = "No match found for "+_ustr(self.expr)
self.myException = ParseException("",0,self.errmsg,self)
 
def parseImpl( self, instring, loc, doActions=True ):
startLoc = loc
instrlen = len(instring)
expr = self.expr
while loc <= instrlen:
try:
loc = expr.skipIgnorables( instring, loc )
expr._parse( instring, loc, doActions=False, callPreParse=False )
if self.includeMatch:
skipText = instring[startLoc:loc]
loc,mat = expr._parse(instring,loc)
if mat:
return loc, [ skipText, mat ]
else:
return loc, [ skipText ]
else:
return loc, [ instring[startLoc:loc] ]
except (ParseException,IndexError):
loc += 1
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Forward(ParseElementEnhance):
"""Forward declaration of an expression to be defined later -
used for recursive grammars, such as algebraic infix notation.
When the expression is known, it is assigned to the Forward variable using the '<<' operator.
Note: take care when assigning to Forward not to overlook precedence of operators.
Specifically, '|' has a lower precedence than '<<', so that::
fwdExpr << a | b | c
will actually be evaluated as::
(fwdExpr << a) | b | c
thereby leaving b and c out as parseable alternatives. It is recommended that you
explicitly group the values inserted into the Forward::
fwdExpr << (a | b | c)
"""
def __init__( self, other=None ):
super(Forward,self).__init__( other, savelist=False )
 
def __lshift__( self, other ):
if isinstance( other, basestring ):
other = Literal(other)
self.expr = other
self.mayReturnEmpty = other.mayReturnEmpty
self.strRepr = None
return self
 
def leaveWhitespace( self ):
self.skipWhitespace = False
return self
 
def streamline( self ):
if not self.streamlined:
self.streamlined = True
if self.expr is not None:
self.expr.streamline()
return self
 
def validate( self, validateTrace=[] ):
if self not in validateTrace:
tmp = validateTrace[:]+[self]
if self.expr is not None:
self.expr.validate(tmp)
self.checkRecursion([])
def __str__( self ):
if hasattr(self,"name"):
return self.name
 
self.__class__ = _ForwardNoRecurse
try:
if self.expr is not None:
retString = _ustr(self.expr)
else:
retString = "None"
finally:
self.__class__ = Forward
return "Forward: "+retString
def copy(self):
if self.expr is not None:
return super(Forward,self).copy()
else:
ret = Forward()
ret << self
return ret
 
class _ForwardNoRecurse(Forward):
def __str__( self ):
return "..."
class TokenConverter(ParseElementEnhance):
"""Abstract subclass of ParseExpression, for converting parsed results."""
def __init__( self, expr, savelist=False ):
super(TokenConverter,self).__init__( expr )#, savelist )
self.saveAsList = False
 
 
class Upcase(TokenConverter):
"""Converter to upper case all matching tokens."""
def __init__(self, *args):
super(Upcase,self).__init__(*args)
def postParse( self, instring, loc, tokenlist ):
return map( string.upper, tokenlist )
 
 
class Downcase(TokenConverter):
"""Converter to upper case all matching tokens."""
def __init__(self, *args):
super(Downcase,self).__init__(*args)
def postParse( self, instring, loc, tokenlist ):
return map( string.lower, tokenlist )
 
 
 
class Combine(TokenConverter):
"""Converter to concatenate all matching tokens to a single string.
By default, the matching patterns must also be contiguous in the input string;
this can be disabled by specifying 'adjacent=False' in the constructor.
"""
def __init__( self, expr, joinString="", adjacent=True ):
super(Combine,self).__init__( expr )
# suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
if adjacent:
self.leaveWhitespace()
self.adjacent = adjacent
self.skipWhitespace = True
self.joinString = joinString
 
def ignore( self, other ):
if self.adjacent:
ParserElement.ignore(self, other)
else:
super( Combine, self).ignore( other )
return self
 
def postParse( self, instring, loc, tokenlist ):
retToks = tokenlist.copy()
del retToks[:]
retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
 
if self.resultsName and len(retToks.keys())>0:
return [ retToks ]
else:
return retToks
 
class Group(TokenConverter):
"""Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions."""
def __init__( self, expr ):
super(Group,self).__init__( expr )
self.saveAsList = True
 
def postParse( self, instring, loc, tokenlist ):
return [ tokenlist ]
class Dict(TokenConverter):
"""Converter to return a repetitive expression as a list, but also as a dictionary.
Each element can also be referenced using the first token in the expression as its key.
Useful for tabular report scraping when the first column can be used as a item key.
"""
def __init__( self, exprs ):
super(Dict,self).__init__( exprs )
self.saveAsList = True
 
def postParse( self, instring, loc, tokenlist ):
for i,tok in enumerate(tokenlist):
ikey = _ustr(tok[0]).strip()
if len(tok)==1:
tokenlist[ikey] = ("",i)
elif len(tok)==2 and not isinstance(tok[1],ParseResults):
tokenlist[ikey] = (tok[1],i)
else:
dictvalue = tok.copy() #ParseResults(i)
del dictvalue[0]
if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()):
tokenlist[ikey] = (dictvalue,i)
else:
tokenlist[ikey] = (dictvalue[0],i)
 
if self.resultsName:
return [ tokenlist ]
else:
return tokenlist
 
 
class Suppress(TokenConverter):
"""Converter for ignoring the results of a parsed expression."""
def postParse( self, instring, loc, tokenlist ):
return []
def suppress( self ):
return self
 
 
class OnlyOnce(object):
"""Wrapper for parse actions, to ensure they are only called once."""
def __init__(self, methodCall):
self.callable = ParserElement.normalizeParseActionArgs(methodCall)
self.called = False
def __call__(self,s,l,t):
if not self.called:
results = self.callable(s,l,t)
self.called = True
return results
raise ParseException(s,l,"")
def reset():
self.called = False
 
def traceParseAction(f):
"""Decorator for debugging parse actions."""
f = ParserElement.normalizeParseActionArgs(f)
def z(*paArgs):
thisFunc = f.func_name
s,l,t = paArgs[-3:]
if len(paArgs)>3:
thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) )
try:
ret = f(*paArgs)
except Exception, exc:
sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
raise
sys.stderr.write( "<<leaving %s (ret: %s)\n" % (thisFunc,ret) )
return ret
return z
#
# global helpers
#
def delimitedList( expr, delim=",", combine=False ):
"""Helper to define a delimited list of expressions - the delimiter defaults to ','.
By default, the list elements and delimiters can have intervening whitespace, and
comments, but this can be overridden by passing 'combine=True' in the constructor.
If combine is set to True, the matching tokens are returned as a single token
string, with the delimiters included; otherwise, the matching tokens are returned
as a list of tokens, with the delimiters suppressed.
"""
dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
if combine:
return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
else:
return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
 
def countedArray( expr ):
"""Helper to define a counted list of expressions.
This helper defines a pattern of the form::
integer expr expr expr...
where the leading integer tells how many expr expressions follow.
The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
"""
arrayExpr = Forward()
def countFieldParseAction(s,l,t):
n = int(t[0])
arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
return []
return ( Word(nums).setParseAction(countFieldParseAction) + arrayExpr )
 
def _flatten(L):
if type(L) is not list: return [L]
if L == []: return L
return _flatten(L[0]) + _flatten(L[1:])
 
def matchPreviousLiteral(expr):
"""Helper to define an expression that is indirectly defined from
the tokens matched in a previous expression, that is, it looks
for a 'repeat' of a previous expression. For example::
first = Word(nums)
second = matchPreviousLiteral(first)
matchExpr = first + ":" + second
will match "1:1", but not "1:2". Because this matches a
previous literal, will also match the leading "1:1" in "1:10".
If this is not desired, use matchPreviousExpr.
Do *not* use with packrat parsing enabled.
"""
rep = Forward()
def copyTokenToRepeater(s,l,t):
if t:
if len(t) == 1:
rep << t[0]
else:
# flatten t tokens
tflat = _flatten(t.asList())
rep << And( [ Literal(tt) for tt in tflat ] )
else:
rep << Empty()
expr.addParseAction(copyTokenToRepeater)
return rep
def matchPreviousExpr(expr):
"""Helper to define an expression that is indirectly defined from
the tokens matched in a previous expression, that is, it looks
for a 'repeat' of a previous expression. For example::
first = Word(nums)
second = matchPreviousExpr(first)
matchExpr = first + ":" + second
will match "1:1", but not "1:2". Because this matches by
expressions, will *not* match the leading "1:1" in "1:10";
the expressions are evaluated first, and then compared, so
"1" is compared with "10".
Do *not* use with packrat parsing enabled.
"""
rep = Forward()
e2 = expr.copy()
rep << e2
def copyTokenToRepeater(s,l,t):
matchTokens = _flatten(t.asList())
def mustMatchTheseTokens(s,l,t):
theseTokens = _flatten(t.asList())
if theseTokens != matchTokens:
raise ParseException("",0,"")
rep.setParseAction( mustMatchTheseTokens )
expr.addParseAction(copyTokenToRepeater)
return rep
def _escapeRegexRangeChars(s):
#~ escape these chars: ^-]
for c in r"\^-]":
s = s.replace(c,"\\"+c)
s = s.replace("\n",r"\n")
s = s.replace("\t",r"\t")
return _ustr(s)
def oneOf( strs, caseless=False, useRegex=True ):
"""Helper to quickly define a set of alternative Literals, and makes sure to do
longest-first testing when there is a conflict, regardless of the input order,
but returns a MatchFirst for best performance.
Parameters:
- strs - a string of space-delimited literals, or a list of string literals
- caseless - (default=False) - treat all literals as caseless
- useRegex - (default=True) - as an optimization, will generate a Regex
object; otherwise, will generate a MatchFirst object (if caseless=True, or
if creating a Regex raises an exception)
"""
if caseless:
isequal = ( lambda a,b: a.upper() == b.upper() )
masks = ( lambda a,b: b.upper().startswith(a.upper()) )
parseElementClass = CaselessLiteral
else:
isequal = ( lambda a,b: a == b )
masks = ( lambda a,b: b.startswith(a) )
parseElementClass = Literal
if isinstance(strs,(list,tuple)):
symbols = strs[:]
elif isinstance(strs,basestring):
symbols = strs.split()
else:
warnings.warn("Invalid argument to oneOf, expected string or list",
SyntaxWarning, stacklevel=2)
i = 0
while i < len(symbols)-1:
cur = symbols[i]
for j,other in enumerate(symbols[i+1:]):
if ( isequal(other, cur) ):
del symbols[i+j+1]
break
elif ( masks(cur, other) ):
del symbols[i+j+1]
symbols.insert(i,other)
cur = other
break
else:
i += 1
 
if not caseless and useRegex:
#~ print strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )
try:
if len(symbols)==len("".join(symbols)):
return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) )
else:
return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) )
except:
warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
SyntaxWarning, stacklevel=2)
 
 
# last resort, just use MatchFirst
return MatchFirst( [ parseElementClass(sym) for sym in symbols ] )
 
def dictOf( key, value ):
"""Helper to easily and clearly define a dictionary by specifying the respective patterns
for the key and value. Takes care of defining the Dict, ZeroOrMore, and Group tokens
in the proper order. The key pattern can include delimiting markers or punctuation,
as long as they are suppressed, thereby leaving the significant key text. The value
pattern can include named results, so that the Dict results can include named token
fields.
"""
return Dict( ZeroOrMore( Group ( key + value ) ) )
 
_bslash = "\\"
printables = "".join( [ c for c in string.printable if c not in string.whitespace ] )
 
# convenience constants for positional expressions
empty = Empty().setName("empty")
lineStart = LineStart().setName("lineStart")
lineEnd = LineEnd().setName("lineEnd")
stringStart = StringStart().setName("stringStart")
stringEnd = StringEnd().setName("stringEnd")
 
_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
_printables_less_backslash = "".join([ c for c in printables if c not in r"\]" ])
_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16)))
_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8)))
_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1)
_charRange = Group(_singleChar + Suppress("-") + _singleChar)
_reBracketExpr = "[" + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
 
_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p)
def srange(s):
r"""Helper to easily define string ranges for use in Word construction. Borrows
syntax from regexp '[]' string range definitions::
srange("[0-9]") -> "0123456789"
srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz"
srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
The input string must be enclosed in []'s, and the returned string is the expanded
character set joined into a single string.
The values enclosed in the []'s may be::
a single character
an escaped character with a leading backslash (such as \- or \])
an escaped hex character with a leading '\0x' (\0x21, which is a '!' character)
an escaped octal character with a leading '\0' (\041, which is a '!' character)
a range of any of the above, separated by a dash ('a-z', etc.)
any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.)
"""
try:
return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body])
except:
return ""
 
def replaceWith(replStr):
"""Helper method for common parse actions that simply return a literal value. Especially
useful when used with transformString().
"""
def _replFunc(*args):
return [replStr]
return _replFunc
 
def removeQuotes(s,l,t):
"""Helper parse action for removing quotation marks from parsed quoted strings.
To use, add this parse action to quoted string using::
quotedString.setParseAction( removeQuotes )
"""
return t[0][1:-1]
 
def upcaseTokens(s,l,t):
"""Helper parse action to convert tokens to upper case."""
return [ str(tt).upper() for tt in t ]
 
def downcaseTokens(s,l,t):
"""Helper parse action to convert tokens to lower case."""
return [ str(tt).lower() for tt in t ]
 
def keepOriginalText(s,startLoc,t):
import inspect
"""Helper parse action to preserve original parsed text,
overriding any nested parse actions."""
f = inspect.stack()[1][0]
try:
endloc = f.f_locals["loc"]
finally:
del f
return s[startLoc:endloc]
def _makeTags(tagStr, xml):
"""Internal helper to construct opening and closing tag expressions, given a tag name"""
tagAttrName = Word(alphanums)
if (xml):
tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
openTag = Suppress("<") + Keyword(tagStr) + \
Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
else:
printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] )
tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
openTag = Suppress("<") + Keyword(tagStr,caseless=True) + \
Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
Suppress("=") + tagAttrValue ))) + \
Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
closeTag = Combine("</" + Keyword(tagStr,caseless=not xml) + ">")
openTag = openTag.setResultsName("start"+"".join(tagStr.replace(":"," ").title().split())).setName("<%s>" % tagStr)
closeTag = closeTag.setResultsName("end"+"".join(tagStr.replace(":"," ").title().split())).setName("</%s>" % tagStr)
return openTag, closeTag
 
def makeHTMLTags(tagStr):
"""Helper to construct opening and closing tag expressions for HTML, given a tag name"""
return _makeTags( tagStr, False )
 
def makeXMLTags(tagStr):
"""Helper to construct opening and closing tag expressions for XML, given a tag name"""
return _makeTags( tagStr, True )
 
opAssoc = _Constants()
opAssoc.LEFT = object()
opAssoc.RIGHT = object()
 
def operatorPrecedence( baseExpr, opList ):
"""Helper method for constructing grammars of expressions made up of
operators working in a precedence hierarchy. Operators may be unary or
binary, left- or right-associative. Parse actions can also be attached
to operator expressions.
Parameters:
- baseExpr - expression representing the most basic element for the nested
- opList - list of tuples, one for each operator precedence level in the expression grammar; each tuple is of the form
(opExpr, numTerms, rightLeftAssoc, parseAction), where:
- opExpr is the pyparsing expression for the operator;
may also be a string, which will be converted to a Literal
- numTerms is the number of terms for this operator (must
be 1 or 2)
- rightLeftAssoc is the indicator whether the operator is
right or left associative, using the pyparsing-defined
constants opAssoc.RIGHT and opAssoc.LEFT.
- parseAction is the parse action to be associated with
expressions matching this operator expression (the
parse action tuple member may be omitted)
"""
ret = Forward()
lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') )
for i,operDef in enumerate(opList):
opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
thisExpr = Forward().setName("expr%d" % i)
if rightLeftAssoc == opAssoc.LEFT:
if arity == 1:
matchExpr = Group( lastExpr + opExpr )
elif arity == 2:
matchExpr = Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
else:
raise ValueError, "operator must be unary (1) or binary (2)"
elif rightLeftAssoc == opAssoc.RIGHT:
if arity == 1:
# try to avoid LR with this extra test
if not isinstance(opExpr, Optional):
opExpr = Optional(opExpr)
matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
elif arity == 2:
matchExpr = Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
else:
raise ValueError, "operator must be unary (1) or binary (2)"
else:
raise ValueError, "operator must indicate right or left associativity"
if pa:
matchExpr.setParseAction( pa )
thisExpr << ( matchExpr | lastExpr )
lastExpr = thisExpr
ret << lastExpr
return ret
 
alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xfe]")
 
dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\.))*"').setName("string enclosed in double quotes")
sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\.))*'").setName("string enclosed in single quotes")
quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\.))*')''').setName("quotedString using single or double quotes")
 
# it's easy to get these comment structures wrong - they're very common, so may as well make them available
cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment")
 
htmlComment = Regex(r"<!--[\s\S]*?-->")
restOfLine = Regex(r".*").leaveWhitespace()
dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment")
cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?<!\\)|\Z))").setName("C++ style comment")
 
javaStyleComment = cppStyleComment
pythonStyleComment = Regex(r"#.*").setName("Python style comment")
_noncomma = "".join( [ c for c in printables if c != "," ] )
_commasepitem = Combine(OneOrMore(Word(_noncomma) +
Optional( Word(" \t") +
~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
commaSeparatedList = delimitedList( Optional( quotedString | _commasepitem, default="") ).setName("commaSeparatedList")
 
 
if __name__ == "__main__":
 
def test( teststring ):
print teststring,"->",
try:
tokens = simpleSQL.parseString( teststring )
tokenlist = tokens.asList()
print tokenlist
print "tokens = ", tokens
print "tokens.columns =", tokens.columns
print "tokens.tables =", tokens.tables
print tokens.asXML("SQL",True)
except ParseException, err:
print err.line
print " "*(err.column-1) + "^"
print err
print
 
selectToken = CaselessLiteral( "select" )
fromToken = CaselessLiteral( "from" )
 
ident = Word( alphas, alphanums + "_$" )
columnName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
columnNameList = Group( delimitedList( columnName ) )#.setName("columns")
tableName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
tableNameList = Group( delimitedList( tableName ) )#.setName("tables")
simpleSQL = ( selectToken + \
( '*' | columnNameList ).setResultsName( "columns" ) + \
fromToken + \
tableNameList.setResultsName( "tables" ) )
test( "SELECT * from XYZZY, ABC" )
test( "select * from SYS.XYZZY" )
test( "Select A from Sys.dual" )
test( "Select AA,BB,CC from Sys.dual" )
test( "Select A, B, C from Sys.dual" )
test( "Select A, B, C from Sys.dual" )
test( "Xelect A, B, C from Sys.dual" )
test( "Select A, B, C frox Sys.dual" )
test( "Select" )
test( "Select ^^^ frox Sys.dual" )
test( "Select A, B, C from Sys.dual, Table2 " )
/branches/avendor/debugger/clvpdbg.py
0,0 → 1,944
from pyparsing import *
import serial
 
#------------------------------------------------------------------------------------------------------
# CLASS STACK
#------------------------------------------------------------------------------------------------------
class Stack(object):
def __init__(self):
self.stack = []
def push(self, value):
self.stack.append(value)
def pop(self):
if len(self.stack) == 0:
return None
value = self.stack[-1]
del self.stack[-1]
return value
#------------------------------------------------------------------------------------------------------
# CLASS PROFILER
#------------------------------------------------------------------------------------------------------
class Profiler(object):
def __init__(self):
self.steps = 0
self.load = 0
self.store = 0
self.jumpbranch = 0
self.flag = 0
self.alu = 0
self.movmova = 0
self.vload = 0
self.vstore = 0
self.valu = 0
self.vmov = 0
self.shuffle = 0
self.scalar = 0
self.vector = 0
self.coopsimul = 0
def add(self, irval):
if irval == None:
return
self.steps = self.steps +1
s = False
v = False
#scalar cmd
if (irval & string.atoi("11100000000000000000000000000000",2)) != 0:
s = True
#vector cmd
if (irval & string.atoi("00000000000011100000000000000000",2)) != 0:
v = True
if s == True and v == True:
self.coopsimul = self.coopsimul + 1
else:
if s == True:
self.scalar = self.scalar + 1
if v == True:
self.vector = self.vector + 1
#alu cmd
if (irval & string.atoi("11000000000000000000000000000000",2))\
== string.atoi("01000000000000000000000000000000",2):
self.alu = self.alu +1
#jmp/jcc cmd
if (irval & string.atoi("11100000000000000000000000000000",2))\
== string.atoi("00100000000000000000000000000000",2):
self.jumpbranch = self.jumpbranch +1
#flag
if (irval & string.atoi("11000000000000000000000000000000",2))\
== string.atoi("11000000000000000000000000000000",2):
self.flag = self.flag +1
#load
if (irval & string.atoi("11110000000000000000000000000000",2))\
== string.atoi("10000000000000000000000000000000",2):
self.load = self.load +1
#store
if (irval & string.atoi("11110000000000000000000000000000",2))\
== string.atoi("10100000000000000000000000000000",2):
self.store = self.store +1
#vload
if (irval & string.atoi("11110000000000000000000000000000",2))\
== string.atoi("10010000000000000000000000000000",2):
self.vload = self.vload +1
 
#vstore
if (irval & string.atoi("11111100000000000000000000000000",2))\
== string.atoi("10110000000000000000000000000000",2):
self.vstore = self.vstore +1
#mov
if (irval & string.atoi("11111000000000000000000000000000",2))\
== string.atoi("10111000000000000000000000000000",2):
self.movmova = self.movmova +1
#mova
if (irval & string.atoi("11111100000000000000000000000000",2))\
== string.atoi("10110100000000000000000000000000",2):
self.movmova = self.movmova +1
#valu
if (irval & string.atoi("00000000000011000000000000000000",2))\
== string.atoi("00000000000001000000000000000000",2):
self.valu = self.valu +1
#vmov
if (irval & string.atoi("00000000000011100000000000000000",2))\
== string.atoi("00000000000000100000000000000000",2):
self.vmov = self.vmov +1
#vshuf
if (irval & string.atoi("00000000000011000000000000000000",2))\
== string.atoi("00000000000011000000000000000000",2):
self.shuffle = self.shuffle +1
def printanalysis(self):
if self.steps == 0:
print "No commands since reset"
return
print "Analysis of " + str(self.steps) + " commands is:"
print " " + "jumps / branches :".ljust(30," ") + str(self.jumpbranch).ljust(10," ") + self.toString(self.jumpbranch)
print " " + "flag modifications :".ljust(30," ") + str(self.flag).ljust(10," ") + self.toString(self.flag)
print " " + "scalar load :".ljust(30," ") + str(self.load).ljust(10," ") + self.toString(self.load)
print " " + "scalar store :".ljust(30," ") + str(self.store).ljust(10," ") + self.toString(self.store)
print " " + "vector load :".ljust(30," ") + str(self.vload).ljust(10," ")+ self.toString(self.vload)
print " " + "vector store :".ljust(30," ") + str(self.vstore).ljust(10," ")+ self.toString(self.vstore)
print " " + "scalar alu :".ljust(30," ") + str(self.alu).ljust(10," ")+ self.toString(self.alu)
print " " + "vector alu :".ljust(30," ") + str(self.valu).ljust(10," ")+ self.toString(self.valu)
print " " + "mov / mova :".ljust(30," ") + str(self.movmova).ljust(10," ")+ self.toString(self.movmova)
print " " + "vmov / vmol / vmor :".ljust(30," ") + str(self.vmov).ljust(10," ")+ self.toString(self.vmov)
print " " + "shuffle :".ljust(30," ") + str(self.shuffle).ljust(10," ")+ self.toString(self.shuffle)
print " " + "scalar commands :".ljust(30," ") + str(self.scalar).ljust(10," ")+ self.toString(self.scalar)
print " " + "vector commands :".ljust(30," ") + str(self.vector).ljust(10," ")+ self.toString(self.vector)
print " " + "cooperative / simultaneous :".ljust(30," ") + str(self.coopsimul).ljust(10," ")+ self.toString(self.coopsimul)
def toString(self, cmd):
val = float(cmd) * 100.0 / float(self.steps)
string = ("%.2f" % (val)).rjust(5," ") + " %"
return string
 
#------------------------------------------------------------------------------------------------------
# CLASS DEBUGGER
#------------------------------------------------------------------------------------------------------
class Debugger(object):
stack = Stack()
profiler = Profiler()
profiling = True
def __init__(self, args):
if len(args) > 3 or len(args) < 2:
print
print "usage: python clvpdbg.py portnumber [symboltablefilename]"
print
sys.exit(1)
if len(args) == 3:
symbols = self.getSymbols(args[2])
else:
symbols = None
self.shell(args[1], symbols)
def getSymbols(self, filename):
try:
file = open (filename,"r")
symbols = {}
for s in file.readlines():
x=s.replace("\n","")
symbols[x.split(":")[1].upper()] = string.atoi(x.split(":")[0])
return symbols
except IOError:
print
print "error: unable to open symboltable file: " + filename
sys.exit(1)
def tointeger(self,s):
if s[0] == "$":
return string.atoi(s[1:], base = 16)
if s[0] == "%":
return string.atoi(s[1:], base = 2)
return string.atoi(s)
def shell(self, portnr, symbols):
try:
self.ser = ser = serial.Serial(string.atoi(portnr), 38400, 8, serial.PARITY_NONE, serial.STOPBITS_ONE, Settings().getTimeout(), 0, 0)
except serial.SerialException:
print
print "An error occured while trying to open the serial port"
sys.exit(1)
print "\nWelcome to the CLVP Debugger !!!\n\nEnter 'help' for a list of commands"
print
self.echo(True)
print
while(1):
sys.stdout.write("#")
line=sys.stdin.readline().upper()
if line.strip() != "":
try:
cmd = LineParser().parseLine(line)
if cmd.command == "QUIT" or cmd.command == "EXIT" or cmd.command == "Q":
sys.exit(0)
elif cmd.command == "HELP":
length = 23
print "The following commands are availiable:"
print " " + "C / CLOCK".ljust(length," ") + "-- generate one clock signal for cpu"
print " " + "R / RESET".ljust(length," ") + "-- reset cpu and trace stats"
print " " + "S / STEP [NUMBER]".ljust(length," ") + "-- execute NUMBER instructions"
print " " + "JUMP ADDRESS".ljust(length," ") + "-- execute until command at ADDRESS"
print " " + "M / DATA".ljust(length," ") + "-- display data of memory output"
print " " + "N / ADDR".ljust(length," ") + "-- display memory address line"
print " " + "A".ljust(length," ") + "-- display value of register A"
print " " + "X".ljust(length," ") + "-- display value of register X"
print " " + "Y".ljust(length," ") + "-- display value of register Y "
print " " + "I / IR".ljust(length," ") + "-- display value of instruction register "
print " " + "J / IC".ljust(length," ") + "-- display value of instruction counter "
print " " + "F / FLAGS".ljust(length," ") + "-- display value of various flags and signals"
print " " + "T / STATUS".ljust(length," ") + "-- display value of all registers"
print " " + "E / ECHO".ljust(length," ") + "-- test if device is responding"
print " " + "READ ADDRESS".ljust(length," ") + "-- read memory value at given ADDRESS"
print " " + "WRITE ADDRESS VALUE".ljust(length," ") + "-- write VALUE to given memory ADDRESS"
print " " + "DOWNLOAD ADDRESS COUNT".ljust(length," ") + "-- download data from memory into FILE"
print " " + "UPLOAD ADDRESS".ljust(length," ") + "-- upload data from FILE into memory"
print " " + "CCSTART ADDRESS".ljust(length," ") + "-- start counting clockticks to reach given ADDRESS"
print " " + "CCSTOP".ljust(length," ") + "-- aborts counting clockticks"
print " " + "CCSTATUS".ljust(length," ") + "-- displays clocktick counter status and value"
print " " + "TRACE [NUMBER]".ljust(length," ") + "-- display IC value of last NUMBER commands"
print " " + "PROFILE".ljust(length," ") + "-- show analysis of commands since reset"
print " " + "TOGGLEPROFILING".ljust(length," ") + "-- activate/deaktivate profiling"
print " " + "SYMBOLS".ljust(length," ") + "-- lists symbols imported from file"
print " " + "Q / QUIT / EXIT".ljust(length," ") + "-- exit debugger"
 
elif cmd.command == "SYMBOLS":
if symbols != None:
print "The following symbols are known:"
for k,v in sorted(symbols.iteritems()):
print " 0x" + str(hex(v))[2:].rjust(8,"0").upper() + " : " + k
else:
print "No symbol file given"
elif cmd.command == "CLOCK" or cmd.command == "C":
self.clock(True)
elif cmd.command == "RESET" or cmd.command == "R":
self.reset(True)
self.clock(False)
elif cmd.command == "A":
self.rega(True)
elif cmd.command == "X":
self.regx(True)
elif cmd.command == "Y":
self.regy(True)
elif cmd.command == "FLAGS" or cmd.command == "F":
self.flags(True)
elif cmd.command == "IR" or cmd.command == "I":
self.ir(True)
elif cmd.command == "IC" or cmd.command == "J":
self.ic(True)
elif cmd.command == "STEP" or cmd.command == "S":
if cmd.value != "":
self.step(self.tointeger(cmd.value), True, self.profiling)
else:
self.step(1, True)
elif cmd.command == "TRACE":
if cmd.value != "":
self.trace(self.tointeger(cmd.value))
else:
self.trace(10)
elif cmd.command == "PROFILE":
self.profiler.printanalysis();
elif cmd.command == "JUMP":
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
self.jump(address, True, self.profiling)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
elif cmd.command == "WRITE":
try:
if cmd.newval_value:
newval = self.tointeger(cmd.newval_value)
else:
newval = symbols[cmd.newval_symbol]
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
self.write(address, newval, True)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
except KeyError:
print "Symbol " + cmd.newval_symbol + " is not known"
elif cmd.command == "READ":
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
self.read(address, True)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
 
elif cmd.command == "DOWNLOAD":
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
sys.stdout.write("Enter filename: ")
filename=sys.stdin.readline().lstrip().rstrip()
self.download(address, self.tointeger(cmd.count), filename, True)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
elif cmd.command == "UPLOAD":
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
sys.stdout.write("Enter filename: ")
filename=sys.stdin.readline().lstrip().rstrip()
self.upload(address, filename, True)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
elif cmd.command == "CCSTART":
try:
if cmd.value:
address = self.tointeger(cmd.value)
else:
address = symbols[cmd.symbol]
self.ccstart(address, True)
except KeyError:
print "Symbol " + cmd.symbol + " is not known"
elif cmd.command == "CCSTOP":
self.ccstop(True)
elif cmd.command == "CCSTATUS":
self.ccstatus(True)
 
elif cmd.command == "DATA" or cmd.command == "M":
self.data(True)
elif cmd.command == "ADDR" or cmd.command == "N":
self.addr(True)
elif cmd.command == "STATUS" or cmd.command == "T":
self.status(True)
elif cmd.command == "ECHO" or cmd.command == "E":
self.echo(True)
elif cmd.command == "GO" or cmd.command == "G":
self.go(True)
elif cmd.command == "PAUSE" or cmd.command == "P":
self.pause(True)
elif cmd.command == "TOGGLEPROFILING":
self.toggleprofiling()
except ParseException, err:
print "Unknown command or incorrect parameters"
print
def ccstop(self, verbose = True):
self.ser.write("5")
if self.ser.read(1) != "5":
if verbose == True:
print "Stop clock counter was NOT successful"
return False
if verbose == True:
print "Clock counter has been stopped"
return True
def ccstart(self, address, verbose = True):
if self.pause(False) == False:
if verbose == True:
print "Enter debugging-mode signal NOT accepted"
return False
if self.put("0", address, 0) == False:
if verbose == True:
print "Transmitting address was NOT successful"
return False
self.ser.write("4")
if self.ser.read(1) != "4":
if verbose == True:
print "Start clock counter was NOT successful"
return False
if verbose == True:
print "Clock counter has been started"
return True
def ccstatus(self, verbose = True):
self.ser.write("6")
status = self.ser.read(1)
if status != "":
if ord(status) == 1:
if verbose == True:
print "Counting clock cycles is finished"
else:
if verbose == True:
print "Counting clock cycles is NOT finished, yet"
else:
if verbose == True:
print "Request to get status was NOT successful"
return None
return self.get32BitReg("Clock cycles","7", verbose)
def toggleprofiling(self):
if self.profiling == False:
self.profiling = True
print "Profiling now ON"
else:
self.profiling = False
print "Profiling now OFF"
def upload(self, address, filename, verbose = True):
try:
f=open(filename,"rb")
i = 0
while f:
x3 = f.read(1)
x2 = f.read(1)
x1 = f.read(1)
x0 = f.read(1)
if x0 == "" or x1 == "" or x2 == "" or x3 == "":
f.close()
print "File has been uploaded"
return True
value = ord(x0) + ord(x1) * 256 + ord(x2) * 256 * 256 + ord(x3) * 256 * 256 * 256
trys = 0
done = False
s = Settings()
while trys < s.getRetrys() and done == False:
if self.write(address + i, value, False) == False:
trys = trys +1
else:
done = True
if done == False:
if verbose == True:
print "File has NOT been uploaded"
return False
i=i+1
 
except IOError:
print "File IO-error occured"
def download(self, address, count, filename, verbose = True):
try:
f=open(filename,"wb")
for i in range(count):
value = self.read(address + i, False)
if value == None:
if verbose == True:
print "Download was NOT successful"
return False
m = string.atoi("11111111000000000000000000000000",2)
for j in range(4):
a = (value & m) >> 8 * (3-j)
m = m >> 8
f.write(chr(a))
f.close()
print "Download into file " + filename + " was successful"
except IOError:
print "Unable to write file: " + filename
def read(self, address, verbose = True):
if self.put("0", address, 0) == False:
if verbose == True:
print "Transmitting address was NOT successful"
return None
return self.get32BitReg("value","2", verbose)
def write(self, address, value, verbose = True):
if self.put("0", address, 0) == False:
if verbose == True:
print "Transmitting address was NOT successful"
return False
if self.put("1", value, 0) == False:
if verbose == True:
print "Transmitting data was NOT successful"
return False
self.ser.write("3")
if self.ser.read(1) != "3":
if verbose == True:
print "Write was NOT successful"
return False
else:
if verbose == True:
print "Data has been written"
return True
def put(self, command, value, trys):
err = False
m = string.atoi("11111111000000000000000000000000",2)
self.ser.write(command)
if self.ser.read(1) != command:
return False
for i in range(4):
a = (value & m) >> 8 * (3-i)
m = m >> 8
self.ser.write(chr(a))
if ord(self.ser.read(1)) != a:
err = True
if err == True:
s= Settings()
if trys == s.getRetrys():
return False
return self.put(command, value, trys +1)
else:
return True
def echo(self, verbose = True):
self.ser.write("e")
if self.ser.read(1) == "e":
if verbose == True:
print "Device is responding"
return True
else:
if verbose == True:
print "Device is NOT responding"
return False
def go(self, verbose = True):
self.ser.write("g")
if self.ser.read(1) == "g":
if verbose == True:
print "System now in free-running-mode"
return True
else:
if verbose == True:
print "Enter free-running-mode signal NOT accepted"
return False
def pause(self, verbose = True):
self.ser.write("p")
if self.ser.read(1) == "p":
if verbose == True:
print "System now in debugging-mode"
return True
else:
if verbose == True:
print "Enter debugging-mode signal NOT accepted"
return False
def clock(self, verbose = True):
self.ser.write("c")
clock = self.ser.read(1)
try:
if ord(clock) == 255: #workaround for belkin usb-to-serial-adapter problems ...
return self.clock (verbose)
except TypeError:
if verbose == True:
print "Clock signal NOT accepted"
return False
if clock == "c":
if verbose == True:
print "Clock signal accepted"
return True
else:
if verbose == True:
print "Clock signal NOT accepted"
return False
def reset(self, verbose = True):
self.ser.write("r")
if self.ser.read(1) == "r":
self.stack = Stack();
self.profiler = Profiler()
if verbose == True:
print "Reset signal (CPU, trace, profiler) accepted"
return True
else:
if verbose == True:
print "Reset signal NOT accepted"
return False
def rega(self, verbose = True):
return self.get32BitReg("register a","a", verbose)
def regx(self, verbose = True):
return self.get32BitReg("register x","x", verbose)
def regy(self, verbose = True):
return self.get32BitReg("register y","y", verbose)
def ic(self, verbose = True):
return self.get32BitReg("instruction counter","j", verbose)
def ir(self, verbose = True):
return self.get32BitReg("instruction register","i", verbose)
def data(self, verbose = True):
return self.get32BitReg("memory output data","m", verbose)
def addr(self, verbose = True):
return self.get32BitReg("memory address signal","n", verbose)
def status(self, verbose = True):
return self.data(verbose), self.addr(verbose), self.ir(verbose), self.ic(verbose), self.rega(verbose),\
self.regx(verbose), self.regy(verbose), self.flags(verbose), \
def get32BitReg(self, name, command, verbose = True):
errors = 0
success = 0
while not success and errors < Settings().getRetrys():
self.ser.write(command)
x0=self.ser.read(1)
x1=self.ser.read(1)
x2=self.ser.read(1)
x3=self.ser.read(1)
checksum = self.ser.read(1)
if x0 == "" or x1 == "" or x2 == "" or x3 == "" or checksum == "":
errors = errors + 1
else:
if ord(checksum) != ord(x0) ^ ord(x1) ^ ord(x2) ^ ord(x3):
errors = errors +1
else:
success = 1
if success:
x = ord(x0) + 256 * ord(x1) + 256 * 256 * ord(x2) + 256 * 256 * 256 * ord(x3)
if verbose == True:
print name + ": 0x" + hex(ord(x3))[2:].rjust(2,"0").upper() + hex(ord(x2))[2:].rjust(2,"0").upper() \
+ hex(ord(x1))[2:].rjust(2,"0").upper() + hex(ord(x0))[2:].rjust(2,"0").upper()
return x
else:
print "request to get " + name + " was NOT successful"
return None
def flags(self, verbose = True):
self.ser.write("f")
flags = self.ser.read(1)
if flags != "":
ir_ready = int((ord(flags) & string.atoi("10000000",2)) > 0)
mem_ready = int((ord(flags) & string.atoi("01000000",2)) > 0)
mem_access = (ord(flags) & string.atoi("00111000",2)) >> 3
mem_access_0 = int((mem_access & 1) > 0)
mem_access_1 = int((mem_access & 2) > 0)
mem_access_2 = int((mem_access & 4) > 0)
halted = int((ord(flags) & string.atoi("00000100",2)) > 0)
zero = int((ord(flags) & string.atoi("00000010",2)) > 0)
carry = int((ord(flags) & string.atoi("00000001",2)) > 0)
if verbose == True:
print "ir_ready: " + str(ir_ready)
print "mem_ready: " + str(mem_ready)
print "mem_access: " + str(mem_access_2) + str(mem_access_1) + str(mem_access_0)
print "halted: " + str(halted)
print "zero: " + str(zero)
print "carry: " + str(carry)
return ir_ready, mem_ready, mem_access, halted, zero, carry
else:
print "Request to get flags was NOT successful"
return None
def step(self, steps, verbose = True, profile = True):
ticks = 0
ic = None
for i in range(steps):
ir_ready = 0
clocks = 0
 
while(ir_ready == 0):
if self.clock(False) == False:
text = "Device is not responding (Clock)"
if verbose == True:
print text
return 0, text, None
flags = self.flags(False)
if flags == None:
text = "Device is not responding (Flags)"
if verbose == True:
print text
return 0, text, None
else:
ir_ready, mem_ready, mem_access, halted, zero, carry = flags
clocks = clocks + 1
if clocks > Settings().getMaxClocks():
text = "Exceeded limit of " + str(Settings().getMaxClocks()) + " clock ticks for one command, aborting"
if verbose == True:
print text
return 0, text, None
ticks = ticks + clocks
ic = self.ic(False)
if profile == True:
self.profiler.add(self.ir(False))
if self.clock(False) == False:
text = "Device is not responding (Clock)"
if verbose == True:
print text
return 0, text, None
ticks = ticks + 1
self.stack.push(ic)
text = "Stepping "+ str(steps) +" command(s) successfull" + "\n" + "Required "+ str(ticks) + " clock ticks"
if verbose == True:
print text
return ticks, text, ic
def jump(self, address, verbose = True, profile = True):
ic = 0
steps = 0
ticks = 0
while(ic != address):
steps = steps +1
clocks, text, ic = self.step(1, False, profile)
if clocks == 0:
if verbose == True:
print "Step " + str(steps) + " was NOT successful"
print text
return 0
if ic == None:
if verbose == True:
print "Device is NOT responding (IC)"
return 0
if steps > Settings().getMaxSteps():
if verbose == True:
print "Exceeded limit of " + str(Settings().getMaxSteps()) + " steps, aborting"
return 0
ticks = ticks + clocks
 
if verbose == True:
print "Instruction counter value after " + str(steps) + " commands reached"
print "Required " + str(ticks) + " clock ticks"
return ticks
def trace(self,n):
print "trace of the last " + str(n) +" instruction counter values: "
import copy
newstack = copy.deepcopy(self.stack)
val = newstack.pop()
x = 0
while( val != None and x < n ):
print "0x" + hex(val)[2:].rjust(8,"0").upper()
val = newstack.pop()
x = x + 1
#------------------------------------------------------------------------------------------------------
# CLASS LINEPARSER
#------------------------------------------------------------------------------------------------------
class LineParser:
def parseLine(self,line):
expression = Forward()
dec_value = Word("0123456789", min=1)
hex_value = Word("$","ABCDEF0123456789", min=2)
bin_value = Word("%","10", min=2)
value = (dec_value ^ hex_value ^ bin_value).setResultsName("value")
ident = Word( alphas, alphanums + "_" ).setResultsName("symbol")
address = (value ^ ident).setResultsName("address")
newval_value = (dec_value ^ hex_value ^ bin_value).setResultsName("newval_value")
newval_ident = Word( alphas, alphanums + "_" ).setResultsName("newval_symbol")
newval_address = (newval_value ^ newval_ident).setResultsName("newval_address")
count = (dec_value ^ hex_value ^ bin_value).setResultsName("count")
cmd_1 = ( Keyword("C") ^ Keyword("CLOCK") ^ Keyword("RESET")^ Keyword("R") ^ Keyword("A") ^ Keyword("X") ^ Keyword("Y") \
^ Keyword("FLAGS") ^ Keyword("F") ^ Keyword("IR") ^ Keyword("IC") ^ Keyword("ECHO") ^ Keyword("QUIT") \
^ Keyword("Q") ^ Keyword("STATUS") ^ Keyword("E") ^ Keyword("HELP") ^ Keyword("EXIT") ^ Keyword("I") \
^ Keyword("J") ^ Keyword("T") ^ Keyword("M") ^Keyword("N") ^ Keyword("ADDR") ^ Keyword("DATA") \
^ Keyword("GO") ^ Keyword("PAUSE") ^ Keyword("G") ^ Keyword("P") ^ Keyword("SYMBOLS") ^ Keyword("PROFILE")
^ Keyword("TOGGLEPROFILING")).setResultsName("command")
cmd_2 = ((Keyword("STEP") ^ Keyword("S")).setResultsName("command")) ^ ((Keyword("STEP") ^ Keyword("S")).setResultsName("command") + value)
cmd_3 = Keyword("JUMP").setResultsName("command") + address
cmd_4 = ((Keyword("TRACE")).setResultsName("command")) ^ ((Keyword("TRACE")).setResultsName("command") + value)
cmd_5 = (Keyword("WRITE")).setResultsName("command") + address + newval_address
cmd_6 = (Keyword("READ")).setResultsName("command") + address
cmd_7 = (Keyword("UPLOAD")).setResultsName("command") + address
cmd_8 = (Keyword("DOWNLOAD")).setResultsName("command") + address + count
cmd_9 = (Keyword("CCSTART")).setResultsName("command") + address
cmd_10 = (Keyword("CCSTOP")).setResultsName("command")
cmd_11 = (Keyword("CCSTATUS")).setResultsName("command")
command = (cmd_1 ^ cmd_2 ^ cmd_3 ^ cmd_4 ^ cmd_5 ^ cmd_6 ^ cmd_7 ^ cmd_8 ^ cmd_9 ^ cmd_10 ^ cmd_11)
expression << command + lineEnd
result = expression.parseString(line)
return result
 
#------------------------------------------------------------------------------------------------------
# CLASS SETTINGS
#------------------------------------------------------------------------------------------------------
class Settings(object):
def getMaxClocks(self):
return 100
def getMaxSteps(self):
return 50000
def getRetrys(self):
return 15
def getTimeout(self):
return 0.1
#------------------------------------------------------------------------------------------------------
# MAIN PROGRAM
#------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
import sys
Debugger(sys.argv)
/branches/avendor/cpu/groups/registergroup.vhd
0,0 → 1,127
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: registergroup
--
-- PURPOSE: register file and destination multiplexer
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity registergroup is
port( -- clock
clk: in std_logic;
-- data inputs
result_in: in std_logic_vector(31 downto 0); -- data from alu
vector_in: in std_logic_vector(31 downto 0); -- data from vector unit
ic_in: in std_logic_vector(31 downto 0); -- instruction
enable_in: in std_logic; -- c6
-- data outputs
x_out: out std_logic_vector(31 downto 0);
y_out: out std_logic_vector(31 downto 0);
a_out: out std_logic_vector(31 downto 0);
-- control signals
sel_source: in std_logic_vector(1 downto 0); -- cc2
sel_dest: in std_logic_vector(1 downto 0) -- dd
);
end registergroup;
 
architecture rtl of registergroup is
component dataregister
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
component multiplexer4
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
component demultiplexer1x4
port( selector: in std_logic_vector(1 downto 0);
data_in: in std_logic;
data_out_00: out std_logic;
data_out_01: out std_logic;
data_out_10: out std_logic;
data_out_11: out std_logic
);
end component;
for reg_x: dataregister use entity work.dataregister(rtl);
for reg_y: dataregister use entity work.dataregister(rtl);
for reg_a: dataregister use entity work.dataregister(rtl);
for mux_input: multiplexer4 use entity work.multiplexer4(rtl);
for demux: demultiplexer1x4 use entity work.demultiplexer1x4(rtl);
signal data_in: std_logic_vector(31 downto 0);
signal load_x: std_logic;
signal load_y: std_logic;
signal load_a: std_logic;
begin
mux_input: multiplexer4
generic map (
w => 32
)
port map (
selector => sel_source,
data_in_00 => result_in,
data_in_01 => ic_in,
data_in_10 => vector_in,
data_in_11 => "--------------------------------",
data_out => data_in
);
demux: demultiplexer1x4 port map (
selector => sel_dest,
data_in => enable_in,
data_out_00 => open,
data_out_01 => load_a,
data_out_10 => load_x,
data_out_11 => load_y
);
reg_x: dataregister port map(
clk => clk,
load => load_x,
data_in => data_in,
data_out => x_out
);
reg_y: dataregister port map(
clk => clk,
load => load_y,
data_in => data_in,
data_out => y_out
);
reg_a: dataregister port map(
clk => clk,
load => load_a,
data_in => data_in,
data_out => a_out
);
end rtl;
/branches/avendor/cpu/groups/vector_slice.vhd
0,0 → 1,177
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: vector_slice
--
-- PURPOSE: slice of the vector executionunit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity vector_slice is
generic (
slicenr : natural := 0
);
port (
-- clock
clk: in std_logic;
-- data inputs
memory_in: in std_logic_vector(31 downto 0);
scalar_in: in std_logic_vector(31 downto 0);
shuffle_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
rshift_in: in std_logic;
-- data outputs
v_out: out std_logic_vector(31 downto 0);
w_out: out std_logic_vector(31 downto 0);
carry_out: out std_logic;
-- control signals
rrrr: in std_logic_vector(7 downto 0);
vvvv: in std_logic_vector(7 downto 0);
wwww: in std_logic_vector(3 downto 0);
k_in: in std_logic_vector(31 downto 0);
load_r: in std_logic;
cc9: in std_logic_vector(1 downto 0);
c12: in std_logic;
-- valu control signals
valuop: in std_logic_vector(3 downto 0);
source_sel: in std_logic_vector(1 downto 0);
carry_sel: in std_logic_vector(1 downto 0);
mult_source_sel: in std_logic_vector(1 downto 0); -- *
mult_dest_sel: in std_logic_vector(1 downto 0); -- *
reg_input_sel: in std_logic; -- *
load_lsr: in std_logic;
load_other: in std_logic
);
end vector_slice;
 
architecture rtl of vector_slice is
component multiplexer4
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
component vector_alu_32
port(
clk: in std_logic;
v_in: in std_logic_vector(31 downto 0);
w_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
rshift_in: in std_logic;
carry_out: out std_logic;
valu_out: out std_logic_vector(31 downto 0);
valuop: in std_logic_vector(3 downto 0);
source_sel: in std_logic_vector(1 downto 0);
carry_sel: in std_logic_vector(1 downto 0);
mult_source_sel: in std_logic_vector(1 downto 0);
mult_dest_sel: in std_logic_vector(1 downto 0);
reg_input_sel: in std_logic;
load_lsr: in std_logic;
load_other: in std_logic
);
end component;
component vector_register
generic (
n : integer range 1 to 256;
slicenr : natural
);
port (
clk: in std_logic;
r_in: in std_logic_vector(31 downto 0);
v_out: out std_logic_vector(31 downto 0);
w_out: out std_logic_vector(31 downto 0);
load_r: in std_logic;
load_select: in std_logic;
k_in: in std_logic_vector(31 downto 0);
select_v: in std_logic_vector(7 downto 0);
select_w: in std_logic_vector(3 downto 0);
select_r: in std_logic_vector(7 downto 0)
);
end component;
for vreg_input_mux: multiplexer4 use entity work.multiplexer4(rtl);
for valu: vector_alu_32 use entity work.vector_alu_32(rtl);
for vreg: vector_register use entity work.vector_register(rtl);
 
signal v: std_logic_vector(31 downto 0);
signal w: std_logic_vector(31 downto 0);
signal r: std_logic_vector(31 downto 0);
signal valu_result: std_logic_vector(31 downto 0);
begin
v_out <= v;
w_out <= w;
vreg_input_mux: multiplexer4
generic map (w => 32)
port map (
selector => cc9,
data_in_00 => valu_result,
data_in_01 => scalar_in,
data_in_10 => memory_in,
data_in_11 => shuffle_in,
data_out => r
);
vreg: vector_register
generic map (
n => n,
slicenr => slicenr
)
port map (
clk => clk,
r_in => r,
v_out => v,
w_out => w,
load_r => load_r,
load_select => c12,
k_in => k_in,
select_v => vvvv,
select_w => wwww,
select_r => rrrr
);
valu: vector_alu_32
port map (
clk => clk,
v_in => v,
w_in => w,
carry_in => carry_in,
rshift_in => rshift_in,
carry_out => carry_out,
valu_out => valu_result,
valuop => valuop,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other
);
 
end rtl;
/branches/avendor/cpu/groups/addressgroup.vhd
0,0 → 1,89
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: addressgroup
--
-- PURPOSE: consists of and connects components
-- used for adressing the memory interface
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity addressgroup is
port( -- clock
clk: in std_logic;
-- data inputs
address_in: in std_logic_vector(31 downto 0);
-- data outputs
address_out: out std_logic_vector(31 downto 0);
ic_out: out std_logic_vector(31 downto 0);
-- control signals
sel_source: in std_logic; -- c1
inc: in std_logic;
load_ic: in std_logic;
reset_ic: in std_logic
);
end addressgroup;
 
architecture rtl of addressgroup is
component instructioncounter
port( clk: in std_logic;
load: in std_logic;
inc: in std_logic;
reset: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
component multiplexer2
generic (
w : positive -- word width
);
port (
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
 
for ic: instructioncounter use entity work.instructioncounter(rtl);
for mux: multiplexer2 use entity work.multiplexer2(rtl);
 
signal instruction: std_logic_vector(31 downto 0);
begin
ic: instructioncounter port map (
clk => clk,
load => load_ic,
inc => inc,
reset => reset_ic,
data_in => address_in,
data_out => instruction
);
mux: multiplexer2
generic map (
w => 32
)
port map (
selector => sel_source,
data_in_0 => instruction,
data_in_1 => address_in,
data_out => address_out
);
ic_out <= instruction;
end rtl;
/branches/avendor/cpu/groups/vector_executionunit.vhd
0,0 → 1,302
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: vector_executionunit
--
-- PURPOSE: execution unit of the vector unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity vector_executionunit is
port (
-- clock
clk: in std_logic;
-- data inputs
memory_in: in vectordata_type;
scalar_in: in std_logic_vector(31 downto 0);
-- data outputs
memory_out: out vectordata_type;
scalar_out: out std_logic_vector(31 downto 0);
out_valid: out std_logic;
shuffle_valid: out std_logic;
-- control signals
rrrr: in std_logic_vector(3 downto 0);
vvvv: in std_logic_vector(3 downto 0);
wwww: in std_logic_vector(3 downto 0);
k_in: in std_logic_vector(31 downto 0);
vn: in std_logic_vector(7 downto 0); -- immediate value n for vector unit
valuop: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
load_r: in std_logic;
cc9: in std_logic_vector(1 downto 0);
c10: in std_logic;
c11: in std_logic;
c12: in std_logic;
cc13: in std_logic_vector(1 downto 0);
valu_go: in std_logic;
shuffle_go: in std_logic
);
end vector_executionunit;
 
architecture rtl of vector_executionunit is
component selectunit
port (
data_in : in vectordata_type;
k_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
component shuffle
port (
clk: in std_logic;
shuffle_go: in std_logic;
shuffle_valid: out std_logic;
data_in_v: in vectordata_type;
data_in_w: in vectordata_type;
vn: in std_logic_vector(7 downto 0);
ssss: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
shuffle_out_sel: in std_logic_vector(1 downto 0);
data_out: out vectordata_type
);
end component;
component valu_controlunit
port(
clk: in std_logic;
valu_go: in std_logic;
valuop: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
source_sel: out std_logic_vector(1 downto 0);
carry_sel: out std_logic_vector(1 downto 0);
mult_source_sel: out std_logic_vector(1 downto 0);
mult_dest_sel: out std_logic_vector(1 downto 0);
reg_input_sel: out std_logic;
load_lsr: out std_logic;
load_other: out std_logic;
out_valid: out std_logic
);
end component;
component vector_slice
generic (
slicenr : natural := 0
);
port (
clk: in std_logic;
memory_in: in std_logic_vector(31 downto 0);
scalar_in: in std_logic_vector(31 downto 0);
shuffle_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
rshift_in: in std_logic;
v_out: out std_logic_vector(31 downto 0);
w_out: out std_logic_vector(31 downto 0);
carry_out: out std_logic;
rrrr: in std_logic_vector(7 downto 0);
vvvv: in std_logic_vector(7 downto 0);
wwww: in std_logic_vector(3 downto 0);
k_in: in std_logic_vector(31 downto 0);
load_r: in std_logic;
cc9: in std_logic_vector(1 downto 0);
c12: in std_logic;
valuop: in std_logic_vector(3 downto 0);
source_sel: in std_logic_vector(1 downto 0);
carry_sel: in std_logic_vector(1 downto 0);
mult_source_sel: in std_logic_vector(1 downto 0);
mult_dest_sel: in std_logic_vector(1 downto 0);
reg_input_sel: in std_logic;
load_lsr: in std_logic;
load_other: in std_logic
);
end component;
component multiplexer2
generic (
w : positive
);
port(
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
for shuffle_impl: shuffle use entity work.shuffle(rtl);
for selectunit_impl: selectunit use entity work.selectunit(rtl);
for valu_controlunit_impl: valu_controlunit use entity work.valu_controlunit(rtl);
for rrrr_mux: multiplexer2 use entity work.multiplexer2(rtl);
for vvvv_mux: multiplexer2 use entity work.multiplexer2(rtl);
signal carry : std_logic_vector(k-1 downto 0);
signal v_vector : vectordata_type;
signal w_vector : vectordata_type;
signal shuffle_out : vectordata_type;
signal select_v : std_logic_vector(7 downto 0);
signal select_r : std_logic_vector(7 downto 0);
signal sel_r : std_logic_vector(7 downto 0);
signal sel_v : std_logic_vector(7 downto 0);
signal sel_w : std_logic_vector(3 downto 0);
signal rrrr_ext : std_logic_vector(7 downto 0);
signal vvvv_ext : std_logic_vector(7 downto 0);
signal source_sel: std_logic_vector(1 downto 0);
signal carry_sel: std_logic_vector(1 downto 0);
signal mult_source_sel: std_logic_vector(1 downto 0);
signal mult_dest_sel: std_logic_vector(1 downto 0);
signal reg_input_sel: std_logic;
signal load_lsr: std_logic;
signal load_other: std_logic;
 
begin
rrrr_ext <= "0000" & rrrr;
vvvv_ext <= "0000" & vvvv;
rrrr_mux : multiplexer2
generic map (w => 8)
port map (
selector => c10,
data_in_0 => rrrr_ext,
data_in_1 => vn,
data_out => select_r
);
 
vvvv_mux : multiplexer2
generic map (w => 8)
port map (
selector => c11,
data_in_0 => vvvv_ext,
data_in_1 => vn,
data_out => select_v
);
 
-- check index < n
sel_r <= select_r when (select_r < n) else (others => '0');
sel_v <= select_v when (select_v < n) else (others => '0');
sel_w <= wwww when (wwww < n) else (others => '0');
selectunit_impl: selectunit
port map (
data_in => v_vector,
k_in => k_in,
data_out => scalar_out
);
shuffle_impl: shuffle
port map (
clk => clk,
shuffle_go => shuffle_go,
shuffle_valid => shuffle_valid,
data_in_v => v_vector,
data_in_w => w_vector,
vn => vn,
ssss => valuop,
vwidth => vwidth,
shuffle_out_sel => cc13,
data_out => shuffle_out
);
valu_controlunit_impl: valu_controlunit
port map (
clk => clk,
valu_go => valu_go,
valuop => valuop,
vwidth => vwidth,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other,
out_valid => out_valid
);
vector_slice_impl: for i in k-1 downto 0 generate
vector_slice_even: if i mod 2 = 0 generate
slice_even: vector_slice
generic map (
slicenr => i
)
port map (
clk => clk,
memory_in => memory_in(i),
scalar_in => scalar_in,
shuffle_in => shuffle_out(i),
carry_in => '0',
rshift_in => carry(i+1),
v_out => v_vector(i),
w_out => w_vector(i),
carry_out => carry(i),
rrrr => sel_r,
vvvv => sel_v,
wwww => sel_w,
k_in => k_in,
load_r => load_r,
cc9 => cc9,
c12 => c12,
valuop => valuop,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other
);
end generate;
vector_slice_uneven: if i mod 2 = 1 generate
slice_uneven: vector_slice
generic map (
slicenr => i
)
port map (
clk => clk,
memory_in => memory_in(i),
scalar_in => scalar_in,
shuffle_in => shuffle_out(i),
carry_in => carry(i-1),
rshift_in => '0',
v_out => v_vector(i),
w_out => w_vector(i),
carry_out => carry(i),
rrrr => sel_r,
vvvv => sel_v,
wwww => sel_w,
k_in => k_in,
load_r => load_r,
cc9 => cc9,
c12 => c12,
valuop => valuop,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other
);
end generate;
end generate ;
memory_out <= v_vector;
end rtl;
/branches/avendor/cpu/groups/flaggroup.vhd
0,0 → 1,113
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: flaggroup
--
-- PURPOSE: status register, flags
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity flaggroup is
port( -- clock
clk: in std_logic;
-- data inputs
c_in: in std_logic;
z_in: in std_logic;
-- data outputs
c_out: out std_logic;
z_out: out std_logic;
-- control signals
load_c: in std_logic;
load_z: in std_logic;
sel_c: in std_logic_vector(1 downto 0);
sel_z: in std_logic_vector(1 downto 0)
);
end flaggroup;
 
architecture rtl of flaggroup is
component flag
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic;
data_out: out std_logic
);
end component;
component multiplexer4
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
for carry_flag: flag use entity work.flag(rtl);
for zero_flag: flag use entity work.flag(rtl);
for carry_mux: multiplexer4 use entity work.multiplexer4(rtl);
for zero_mux: multiplexer4 use entity work.multiplexer4(rtl);
signal mux_to_c: std_logic;
signal mux_to_z: std_logic;
begin
carry_flag: flag port map (
clk => clk,
load => load_c,
data_in => mux_to_c,
data_out => c_out
);
zero_flag: flag port map (
clk => clk,
load => load_z,
data_in => mux_to_z,
data_out => z_out
);
carry_mux: multiplexer4
generic map
(
w => 1
)
port map (
selector => sel_c,
data_in_00(0) => c_in,
data_in_01(0) => '-',
data_in_10(0) => '0',
data_in_11(0) => '1',
data_out(0) => mux_to_c
);
zero_mux: multiplexer4
generic map
(
w => 1
)
port map (
selector => sel_z,
data_in_00(0) => z_in,
data_in_01(0) => '-',
data_in_10(0) => '0',
data_in_11(0) => '1',
data_out(0) => mux_to_z
);
end rtl;
/branches/avendor/cpu/groups/cpu.vhd
0,0 → 1,368
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: cpu
--
-- PURPOSE: connects components of the
-- scalar unit and the vector unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity cpu is
port(
clk: in std_logic;
reset: in std_logic;
dbg_a: out std_logic_vector(31 downto 0);
dbg_x: out std_logic_vector(31 downto 0);
dbg_y: out std_logic_vector(31 downto 0);
dbg_ir: out std_logic_vector(31 downto 0);
dbg_ic: out std_logic_vector(31 downto 0);
dbg_carry: out std_logic;
dbg_zero: out std_logic;
dbg_ir_ready: out std_logic;
dbg_halted: out std_logic;
mem_data_in: in std_logic_vector(31 downto 0);
mem_data_out: out std_logic_vector(31 downto 0);
mem_vdata_in: in vectordata_type;
mem_vdata_out: out vectordata_type;
mem_address: out std_logic_vector(31 downto 0);
mem_access: out std_logic_vector(2 downto 0);
mem_ready: in std_logic
);
end cpu;
 
architecture rtl of cpu is
component controlunit
port(
clk: in std_logic;
ir: in std_logic_vector(31 downto 0);
reset_cpu: in std_logic;
zero: in std_logic;
carry: in std_logic;
ready: in std_logic;
access_type: out std_logic_vector(2 downto 0);
c0: out std_logic;
c1: out std_logic;
cc2: out std_logic_vector(1 downto 0);
cc4: out std_logic_vector(1 downto 0);
cc5: out std_logic_vector(1 downto 0);
c6: out std_logic;
c7: out std_logic;
c8: out std_logic;
load_ir: out std_logic;
inc_ic: out std_logic;
load_ic: out std_logic;
load_c: out std_logic;
load_z: out std_logic;
ir_ready: out std_logic;
s_ready: out std_logic;
s_fetched: out std_logic;
v_ready: in std_logic;
v_fetched: in std_logic;
v_done: in std_logic;
halted: out std_logic
);
end component;
 
component aluinputgroup
port(
clk: in std_logic;
memory_in: in std_logic_vector(31 downto 0);
x_in: in std_logic_vector(31 downto 0);
y_in: in std_logic_vector(31 downto 0);
a_in: in std_logic_vector(31 downto 0);
ir_out: out std_logic_vector(31 downto 0);
k_out: out std_logic_vector(31 downto 0);
vector_out: out std_logic_vector(31 downto 0);
a_out: out std_logic_vector(31 downto 0);
b_out: out std_logic_vector(31 downto 0);
sel_a: in std_logic_vector(1 downto 0);
sel_b: in std_logic_vector(1 downto 0);
sel_source_a: in std_logic;
sel_source_b: in std_logic;
load_ir: in std_logic
);
end component;
component alu
port(
a_in: in std_logic_vector(31 downto 0);
b_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
aluop: in std_logic_vector(3 downto 0);
op_select: in std_logic;
zero_out: out std_logic;
carry_out: out std_logic;
alu_out: out std_logic_vector(31 downto 0)
);
end component;
component addressgroup
port(
clk: in std_logic;
address_in: in std_logic_vector(31 downto 0);
address_out: out std_logic_vector(31 downto 0);
ic_out: out std_logic_vector(31 downto 0);
sel_source: in std_logic;
inc: in std_logic;
load_ic: in std_logic;
reset_ic: in std_logic
);
end component;
component registergroup
port(
clk: in std_logic;
result_in: in std_logic_vector(31 downto 0);
vector_in: in std_logic_vector(31 downto 0);
ic_in: in std_logic_vector(31 downto 0);
enable_in: in std_logic;
x_out: out std_logic_vector(31 downto 0);
y_out: out std_logic_vector(31 downto 0);
a_out: out std_logic_vector(31 downto 0);
sel_source: in std_logic_vector(1 downto 0);
sel_dest: in std_logic_vector(1 downto 0)
);
end component;
component flaggroup
port(
clk: in std_logic;
c_in: in std_logic;
z_in: in std_logic;
c_out: out std_logic;
z_out: out std_logic;
load_c: in std_logic;
load_z: in std_logic;
sel_c: in std_logic_vector(1 downto 0);
sel_z: in std_logic_vector(1 downto 0)
);
end component;
component vector_controlunit
port(
clk: in std_logic;
ir: in std_logic_vector(31 downto 0);
load_r: out std_logic;
cc9: out std_logic_vector(1 downto 0);
c10: out std_logic;
c11: out std_logic;
c12: out std_logic;
cc13: out std_logic_vector(1 downto 0);
valu_go: out std_logic;
shuffle_go: out std_logic;
out_valid: in std_logic;
shuffle_valid: in std_logic;
ir_ready: in std_logic;
s_ready: in std_logic;
s_fetched: in std_logic;
v_ready: out std_logic;
v_fetched: out std_logic;
v_done: out std_logic
);
end component;
component vector_executionunit
port (
clk: in std_logic;
memory_in: in vectordata_type;
scalar_in: in std_logic_vector(31 downto 0);
memory_out: out vectordata_type;
scalar_out: out std_logic_vector(31 downto 0);
out_valid: out std_logic;
shuffle_valid: out std_logic;
rrrr: in std_logic_vector(3 downto 0);
vvvv: in std_logic_vector(3 downto 0);
wwww: in std_logic_vector(3 downto 0);
k_in: in std_logic_vector(31 downto 0);
vn: in std_logic_vector(7 downto 0);
valuop: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
load_r: in std_logic;
cc9: in std_logic_vector(1 downto 0);
c10: in std_logic;
c11: in std_logic;
c12: in std_logic;
cc13: in std_logic_vector(1 downto 0);
valu_go: in std_logic;
shuffle_go: in std_logic
);
end component;
 
for controlunit_impl: controlunit use entity work.controlunit(rtl);
for aluinputgroup_impl: aluinputgroup use entity work.aluinputgroup(rtl);
for alu_impl: alu use entity work.alu(rtl);
for addressgroup_impl: addressgroup use entity work.addressgroup(rtl);
for registergroup_impl: registergroup use entity work.registergroup(rtl);
for flaggroup_impl: flaggroup use entity work.flaggroup(rtl);
for vector_controlunit_impl: vector_controlunit use entity work.vector_controlunit(rtl);
for vector_executionunit_impl: vector_executionunit use entity work.vector_executionunit(rtl);
-- controlunit signals
signal ir: std_logic_vector(31 downto 0);
signal zero: std_logic;
signal carry: std_logic;
signal c0: std_logic;
signal c1: std_logic;
signal cc2: std_logic_vector(1 downto 0);
signal cc4: std_logic_vector(1 downto 0);
signal cc5: std_logic_vector(1 downto 0);
signal c6: std_logic;
signal c7: std_logic;
signal c8: std_logic;
signal load_ir: std_logic;
signal inc_ic: std_logic;
signal load_ic: std_logic;
signal load_c: std_logic;
signal load_z: std_logic;
signal ir_ready: std_logic;
signal s_ready: std_logic;
signal s_fetched: std_logic;
signal v_ready: std_logic;
signal v_fetched: std_logic;
signal v_done: std_logic;
-- aluinputgroup
signal x: std_logic_vector(31 downto 0);
signal y: std_logic_vector(31 downto 0);
signal a: std_logic_vector(31 downto 0);
signal k_out: std_logic_vector(31 downto 0);
signal vector_out: std_logic_vector(31 downto 0);
signal alu_input_a: std_logic_vector(31 downto 0);
signal alu_input_b: std_logic_vector(31 downto 0);
-- alu signals
signal aluop: std_logic_vector(3 downto 0) ;
signal zero_out: std_logic;
signal carry_out: std_logic;
signal alu_out: std_logic_vector(31 downto 0);
-- address group signals
signal ic: std_logic_vector(31 downto 0);
-- register group signals
signal vector_in: std_logic_vector(31 downto 0);
-- signals from instruction
signal ss: std_logic_vector(1 downto 0);
signal dd: std_logic_vector(1 downto 0);
signal tt: std_logic_vector(1 downto 0);
-- vector_controlunit signals
signal load_r: std_logic;
signal cc9: std_logic_vector(1 downto 0);
signal c10: std_logic;
signal c11: std_logic;
signal c12: std_logic;
signal cc13: std_logic_vector(1 downto 0);
signal valu_go: std_logic;
signal out_valid: std_logic;
signal shuffle_go: std_logic;
signal shuffle_valid: std_logic;
-- vector_executionunit signals
signal rrrr: std_logic_vector(3 downto 0);
signal vvvv: std_logic_vector(3 downto 0);
signal wwww: std_logic_vector(3 downto 0);
signal vn: std_logic_vector(7 downto 0);
signal valuop: std_logic_vector(3 downto 0);
signal vwidth: std_logic_vector(1 downto 0);
begin
controlunit_impl: controlunit
port map (
clk => clk, ir => ir, reset_cpu => reset, zero => zero, carry => carry, ready => mem_ready,
access_type => mem_access, c0 => c0, c1 => c1, cc2 => cc2, cc4 => cc4, cc5 => cc5,
c6 => c6, c7 => c7, c8 => c8, load_ir => load_ir, inc_ic => inc_ic, load_ic => load_ic,
load_c => load_c, load_z => load_z, ir_ready => ir_ready, s_ready =>
s_ready, s_fetched => s_fetched,v_ready => v_ready, v_fetched => v_fetched, v_done => v_done,
halted => dbg_halted
);
aluinputgroup_impl: aluinputgroup
port map (
clk => clk, memory_in => mem_data_in, x_in => x, y_in => y, a_in => a, ir_out => ir, k_out => k_out,
vector_out => vector_out, a_out => alu_input_a, b_out => alu_input_b, sel_a => ss, sel_b => tt,
sel_source_a => c8, sel_source_b => c0, load_ir => load_ir
);
alu_impl: alu
port map (
a_in => alu_input_a, b_in => alu_input_b, carry_in => carry, aluop => aluop,
op_select => c7, carry_out => carry_out, zero_out => zero_out, alu_out => alu_out
);
addressgroup_impl: addressgroup
port map (
clk => clk, address_in => alu_out, address_out => mem_address, ic_out => ic, sel_source => c1,
inc => inc_ic, load_ic => load_ic, reset_ic => reset
);
registergroup_impl: registergroup
port map (
clk => clk, result_in => alu_out, vector_in => vector_in,
ic_in => ic, enable_in => c6, x_out => x, y_out => y, a_out => a,
sel_source => cc2, sel_dest => dd
);
flaggroup_impl: flaggroup
port map (
clk => clk, c_in => carry_out, z_in => zero_out, c_out => carry,
z_out => zero, load_c => load_c, load_z => load_z, sel_c => cc5, sel_z => cc4
);
vector_controlunit_impl: vector_controlunit
port map (
clk => clk, ir => ir, load_r => load_r, cc9 => cc9, c10 => c10, c11 => c11,
c12 => c12, cc13 => cc13, valu_go => valu_go, shuffle_go => shuffle_go, out_valid => out_valid,
shuffle_valid => shuffle_valid, ir_ready => ir_ready, s_ready => s_ready, s_fetched => s_fetched,
v_ready => v_ready, v_fetched => v_fetched, v_done => v_done
);
vector_executionunit_impl: vector_executionunit
port map (
clk => clk, memory_in => mem_vdata_in, scalar_in => vector_out, memory_out => mem_vdata_out,
scalar_out => vector_in, out_valid => out_valid, shuffle_valid => shuffle_valid, rrrr => rrrr,
vvvv => vvvv, wwww => wwww, k_in => k_out, vn => vn, valuop => valuop, vwidth => vwidth,
load_r => load_r, cc9 => cc9, c10 => c10, c11 => c11, c12 => c12, cc13 => cc13, valu_go => valu_go,
shuffle_go => shuffle_go
);
 
-- from ir derived signals
dd <= ir (25 downto 24);
ss <= ir (23 downto 22);
tt <= ir (21 downto 20);
aluop <= ir (29 downto 26);
rrrr <= ir (11 downto 8);
vvvv <= ir (7 downto 4);
wwww <= ir (3 downto 0);
vn <= ir (27 downto 20);
valuop <= ir (15 downto 12);
vwidth <= ir (17 downto 16);
 
-- memory interfaces signals
mem_data_out <= a;
-- debugging signals
dbg_a <= a;
dbg_x <= x;
dbg_y <= y;
dbg_ir <= ir;
dbg_ic <= ic;
dbg_carry <= carry;
dbg_zero <= zero;
dbg_ir_ready <= ir_ready;
end;
/branches/avendor/cpu/groups/aluinputgroup.vhd
0,0 → 1,156
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: aluinputgroup
--
-- PURPOSE: consists of and connects components
-- used to switch inputs for the scalar
-- alu
-- also includes instruction register
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity aluinputgroup is
port( -- clock
clk: in std_logic;
-- data inputs
memory_in: in std_logic_vector(31 downto 0); -- data from ram
x_in: in std_logic_vector(31 downto 0);
y_in: in std_logic_vector(31 downto 0);
a_in: in std_logic_vector(31 downto 0);
-- data outputs
ir_out: out std_logic_vector(31 downto 0);
k_out: out std_logic_vector(31 downto 0); -- k for vector unit
vector_out: out std_logic_vector(31 downto 0); -- data for vector unit
a_out: out std_logic_vector(31 downto 0);
b_out: out std_logic_vector(31 downto 0);
-- control signals
sel_a: in std_logic_vector(1 downto 0);
sel_b: in std_logic_vector(1 downto 0);
sel_source_a: in std_logic; -- c8
sel_source_b: in std_logic; -- c0
load_ir: in std_logic
);
end aluinputgroup;
 
architecture rtl of aluinputgroup is
component dataregister
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
component multiplexer4
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
component multiplexer2
generic (
w : positive
);
port (
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
 
for ir: dataregister use entity work.dataregister(rtl);
for mux_a: multiplexer4 use entity work.multiplexer4(rtl);
for mux_b: multiplexer4 use entity work.multiplexer4(rtl);
for mux_source_b: multiplexer2 use entity work.multiplexer2(rtl);
for mux_source_a: multiplexer2 use entity work.multiplexer2(rtl);
signal instruction: std_logic_vector(31 downto 0);
signal n: std_logic_vector(31 downto 0);
signal mux_a_to_source: std_logic_vector(31 downto 0);
signal mux_b_to_source: std_logic_vector(31 downto 0);
begin
ir: dataregister
port map (
clk => clk,
load => load_ir,
data_in => memory_in,
data_out => instruction
);
mux_a: multiplexer4
generic map (
w => 32
)
port map (
selector => sel_a,
data_in_00 => "00000000000000000000000000000000",
data_in_01 => a_in,
data_in_10 => x_in,
data_in_11 => y_in,
data_out => mux_a_to_source
);
mux_b: multiplexer4
generic map (
w => 32
)
port map (
selector => sel_b,
data_in_00 => n,
data_in_01 => a_in,
data_in_10 => x_in,
data_in_11 => y_in,
data_out => mux_b_to_source
);
mux_source_a: multiplexer2
generic map (
w => 32
)
port map (
selector => sel_source_a,
data_in_0 => mux_a_to_source,
data_in_1 => "00000000000000000000000000000000",
data_out => a_out
);
mux_source_b: multiplexer2
generic map (
w => 32
)
port map (
selector => sel_source_b,
data_in_0 => mux_b_to_source,
data_in_1 => memory_in,
data_out => b_out
);
n(15 downto 0) <= instruction(15 downto 0);
n(31 downto 16) <= "0000000000000000";
k_out <= mux_b_to_source;
vector_out <= mux_a_to_source;
ir_out <= instruction;
 
end rtl;
/branches/avendor/cpu/units/vector_controlunit.vhd
0,0 → 1,274
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: vector_controlunit
--
-- PURPOSE: controlunit for vector unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
use work.cfg.all;
 
entity vector_controlunit is
port(
-- clock
clk: in std_logic; -- clock signal
-- instruction in
ir: in std_logic_vector(31 downto 0); -- instruction
-- control signals out
load_r: out std_logic;
cc9: out std_logic_vector(1 downto 0);
c10: out std_logic;
c11: out std_logic;
c12: out std_logic;
cc13: out std_logic_vector(1 downto 0);
valu_go: out std_logic;
shuffle_go: out std_logic;
-- control signals in
out_valid: in std_logic;
shuffle_valid: in std_logic;
-- communication with scalar unit
ir_ready: in std_logic; -- next instruction has been loaded into ir
s_ready: in std_logic; -- data from scalar unit or mi is ready
s_fetched: in std_logic; -- signal for vector unit to continue
 
v_ready: out std_logic; -- data for scalar unit or mi is ready
v_fetched: out std_logic; -- signal for scalar unit to continue
v_done: out std_logic -- vector unit completed command
);
end vector_controlunit;
 
architecture rtl of vector_controlunit is
type statetype is (wfi, decode_wait, vmovrv, vmovrrn, vmovrnv, valu1, valu2, valu3, vld, vtos,
movrts, mova, shuffle1, shuffle2, shuffle3, vmol, vmor);
signal state : statetype := wfi;
signal nextstate : statetype := wfi;
 
begin
 
-- state register
process
begin
wait until clk='1' and clk'event;
state <= nextstate;
end process;
-- state transitions
process (state, ir, ir_ready, s_ready, s_fetched, out_valid, shuffle_valid)
begin
-- avoid latches
load_r <= '0';
cc9 <= "00";
c10 <= '0';
c11 <= '0';
c12 <= '0';
cc13 <= "00";
v_ready <= '0';
v_fetched <= '0';
v_done <= '0';
valu_go <= '0';
shuffle_go <= '0';
nextstate <= wfi;
case state is
-- WAIT FOR INSTRUCTION STATE --
when wfi =>
if ir_ready = '1' then
nextstate <= decode_wait;
else
v_done <= '1';
nextstate <= wfi;
end if;
-- DECODE AND WAIT STATE --
when decode_wait =>
case ir(19 downto 18) is
when "00" =>
if ir(17) = '0' then -- vnop
nextstate <= wfi;
else
case ir(15 downto 12) is
when "0001" => -- vmov r,v
nextstate <= vmovrv;
when "0010" => -- vmov r, R<n>
nextstate <= vmovrrn;
when "0011" => -- vmov R<n>, v
nextstate <= vmovrnv;
when "1000" => -- vmol r,v
nextstate <= vmol;
when "1100" => -- vmor r,v
nextstate <= vmor;
when others => -- error => ignore command
nextstate <= wfi;
end case;
end if;
 
when "01" => -- valu
nextstate <= valu1;
when "10" => -- vld/vst/move
case ir(15 downto 12) is
when "0010" => -- vld
if s_ready = '1' then
nextstate <= vld;
else
nextstate <= decode_wait;
end if;
when "0011" | "0101" => -- vst, mov d, v(t)
nextstate <= vtos;
when "0100" => -- mov r(t), s
if s_ready = '1' then
nextstate <= movrts;
else
nextstate <= decode_wait;
end if;
when "0110" => -- mova
if s_ready = '1' then
nextstate <= mova;
else
nextstate <= decode_wait;
end if;
when others => -- error => ignore command
nextstate <= wfi;
end case;
when "11" => -- shuffle
if use_shuffle then
nextstate <= shuffle1;
else
nextstate <= wfi;
end if;
when others => -- error
nextstate <= wfi;
end case;
-- VMOL R,V STATE --
when vmol =>
cc13 <= "10";
cc9 <= "11";
load_r <= '1';
nextstate <= wfi;
-- VMOR R,V STATE --
when vmor =>
cc13 <= "11";
cc9 <= "11";
load_r <= '1';
nextstate <= wfi;
-- VMOV R,V STATE --
when vmovrv =>
cc13 <= "01";
cc9 <= "11";
load_r <= '1';
nextstate <= wfi;
-- VMOV R,R<N> STATE --
when vmovrrn =>
cc13 <= "01";
cc9 <= "11";
c11 <= '1';
load_r <= '1';
nextstate <= wfi;
-- VMOV R<N>,V STATE --
when vmovrnv =>
cc13 <= "01";
cc9 <= "11";
c10 <= '1';
load_r <= '1';
nextstate <= wfi;
-- VALU COMMAND STATE --
when valu1 =>
valu_go <= '1';
nextstate <= valu2;
when valu2 =>
if out_valid = '0' then
nextstate <= valu2;
else
nextstate <= valu3;
end if;
when valu3 =>
load_r <= '1';
nextstate <= wfi;
-- VLD STATE --
when vld =>
cc9 <= "10";
load_r <= '1';
v_fetched <= '1';
nextstate <= wfi;
-- VECTOR TO SCALAR STATE --
when vtos =>
v_ready <= '1';
if s_fetched = '1' then
nextstate <= wfi;
else
nextstate <= vtos;
end if;
-- MOV R(T),S STATE --
when movrts =>
cc9 <= "01";
c12 <= '1';
load_r <= '1';
v_fetched <= '1';
nextstate <= wfi;
-- MOVA STATE --
when mova =>
cc9 <= "01";
load_r <= '1';
v_fetched <= '1';
nextstate <= wfi;
 
-- SHUFFLE STATES
when shuffle1 =>
shuffle_go <= '1';
nextstate <= shuffle2;
when shuffle2 =>
if shuffle_valid = '0' then
nextstate <= shuffle2;
else
nextstate <= shuffle3;
end if;
when shuffle3 =>
cc9 <= "11";
load_r <= '1';
nextstate <= wfi;
end case;
end process;
end rtl;
 
/branches/avendor/cpu/units/sram.vhd
0,0 → 1,47
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: sram
--
-- PURPOSE: sram memory
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
 
entity sram is
port (
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(31 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end sram;
 
architecture rtl of sram is
type memory_type is array(0 to sram_size) of std_logic_vector(31 downto 0);
signal memory : memory_type;
begin
process (clk)
begin
if clk'event and clk = '1' then
if en = '1' then
if we = '1' then
memory(conv_integer(addr)) <= di;
do <= di;
else
do <= memory(conv_integer(addr));
end if;
end if;
end if;
end process;
end;
/branches/avendor/cpu/units/vector_register.vhd
0,0 → 1,68
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: vector_register
--
-- PURPOSE: 32 bit register file for vector_slice
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity vector_register is
generic (
n : integer range 1 to 256;
slicenr : natural
);
port (
-- clock
clk: in std_logic;
-- data inputs
r_in: in std_logic_vector(31 downto 0);
-- data outputs
v_out: out std_logic_vector(31 downto 0);
w_out: out std_logic_vector(31 downto 0);
-- control signals
load_r: in std_logic;
load_select: in std_logic;
k_in: in std_logic_vector(31 downto 0);
select_v: in std_logic_vector(7 downto 0);
select_w: in std_logic_vector(3 downto 0);
select_r: in std_logic_vector(7 downto 0)
);
end vector_register;
architecture rtl of vector_register is
type regfile_type is array(0 to n-1) of std_logic_vector(31 downto 0);
signal regfile : regfile_type := (others => (others => '0'));
begin
process
begin
wait until clk='1' and clk'event;
if (load_r = '1' and load_select /= '1') or (load_r = '1' and load_select = '1'
and k_in = slicenr) then
regfile(conv_integer(select_r)) <= r_in;
end if;
v_out <= regfile(conv_integer(select_v));
w_out <= regfile(conv_integer(select_w));
end process;
end rtl;
 
/branches/avendor/cpu/units/valu_controlunit.vhd
0,0 → 1,220
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: valu_controlunit
--
-- PURPOSE: common controlunit of the
-- vector alus
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
 
entity valu_controlunit is
port(
clk: in std_logic;
valu_go: in std_logic;
valuop: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
source_sel: out std_logic_vector(1 downto 0);
carry_sel: out std_logic_vector(1 downto 0);
mult_source_sel: out std_logic_vector(1 downto 0);
mult_dest_sel: out std_logic_vector(1 downto 0);
reg_input_sel: out std_logic;
load_lsr: out std_logic;
load_other: out std_logic;
out_valid: out std_logic
);
end;
 
architecture rtl of valu_controlunit is
type statetype is (waiting, vlsr, vlsr64, vother, vother64, vmult8, vmult16);
signal state : statetype := waiting;
signal nextstate : statetype := waiting;
signal counter: unsigned(1 downto 0) := "00";
signal inc, reset: std_logic;
begin
-- counter
process
variable x : unsigned(1 downto 0);
begin
wait until clk ='1' and clk'event;
if reset = '1' then
counter <= (others => '0');
else
if inc = '1' then
x := unsigned(counter);
counter <= counter + 1;
end if;
end if;
end process;
-- state register
process
begin
wait until clk ='1' and clk'event;
state <= nextstate;
end process;
-- state transitions
process (state, valu_go, valuop, vwidth, counter)
variable lsr_result: unsigned(8 downto 0);
begin
-- avoid latches
out_valid <= '0';
reset <= '0';
inc <= '0';
load_lsr <= '0';
load_other <= '0';
mult_source_sel <= "00";
mult_dest_sel <= "00";
reg_input_sel <= '0';
case state is
-- waiting for go command from vector controlunit
when waiting =>
out_valid <= '1';
reset <= '1';
nextstate <= waiting;
if valu_go = '1' then
case valuop is
when "1110" =>
nextstate <= vlsr;
when "1011" =>
if vwidth(0) = '0' then
nextstate <= vmult8;
else
nextstate <= vmult16;
end if;
when others =>
nextstate <= vother;
end case;
else
nextstate <= waiting;
end if;
-- normal alu commands
when vother =>
inc <= '1';
load_other <= '1';
if counter = 3 then
if vwidth = "11" then
nextstate <= vother64;
else
nextstate <= waiting;
end if;
else
nextstate <= vother;
end if;
-- normal alu commands 64 bit
when vother64 =>
inc <= '1';
load_other <= '1';
if counter = 3 then
nextstate <= waiting;
else
nextstate <= vother64;
end if;
-- vector shift right command
when vlsr =>
inc <= '1';
load_lsr <= '1';
if counter = 3 then
if vwidth = "11" then
nextstate <= vlsr64;
else
nextstate <= waiting;
end if;
else
nextstate <= vlsr;
end if;
-- vector shift right command 64 bit
when vlsr64 =>
inc <= '1';
load_lsr <= '1';
if counter = 3 then
nextstate <= waiting;
else
nextstate <= vlsr64;
end if;
-- multiplication with 8 bit
when vmult8 =>
inc <= '1';
load_other <= '1';
reg_input_sel <= '1';
case counter is
when "00" =>
mult_source_sel <= "00";
mult_dest_sel <= "00";
nextstate <= vmult8;
when "01" =>
mult_source_sel <= "00";
mult_dest_sel <= "01";
nextstate <= vmult8;
when "10" =>
mult_source_sel <= "01";
mult_dest_sel <= "00";
nextstate <= vmult8;
when "11" =>
mult_source_sel <= "01";
mult_dest_sel <= "01";
nextstate <= waiting;
when others =>
nextstate <= waiting;
end case;
 
-- multiplication with 16 bit
when vmult16 =>
inc <= '1';
load_other <= '1';
mult_source_sel <= "10";
mult_dest_sel <= std_logic_vector(counter);
reg_input_sel <= '1';
if counter = 3 then
nextstate <= waiting;
else
nextstate <= vmult16;
end if;
end case;
end process;
source_sel <= "00" when ( (counter = 0 and valuop /= "1110") or (counter = 3 and valuop = "1110") ) else
"01" when ( (counter = 1 and valuop /= "1110") or (counter = 2 and valuop = "1110") ) else
"10" when ( (counter = 2 and valuop /= "1110") or (counter = 1 and valuop = "1110") ) else
"11";
 
carry_sel <= "00" when (vwidth = "11" and counter = 0) else -- 64 bit
"01" when (vwidth(1) = '1' and counter /= 0) else -- 32 and 64 bit
"01" when (vwidth = "01" and (counter = 1 or counter = 3)) else -- 16 bit
"10"; -- 8 bit
 
end rtl;
/branches/avendor/cpu/units/vector_alu_32.vhd
0,0 → 1,146
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: vector_alu_32
--
-- PURPOSE: 32 bit vector alu
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
use work.cfg.all;
 
entity vector_alu_32 is
port(
-- clock
clk: in std_logic;
-- data in
v_in: in std_logic_vector(31 downto 0);
w_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
rshift_in: in std_logic;
-- data out
carry_out: out std_logic;
valu_out: out std_logic_vector(31 downto 0);
-- control signals
valuop: in std_logic_vector(3 downto 0);
source_sel: in std_logic_vector(1 downto 0);
carry_sel: in std_logic_vector(1 downto 0);
mult_source_sel: in std_logic_vector(1 downto 0); -- *
mult_dest_sel: in std_logic_vector(1 downto 0); -- *
reg_input_sel: in std_logic; -- *
load_lsr: in std_logic;
load_other: in std_logic
);
end;
 
 
architecture rtl of vector_alu_32 is
 
signal carry, rshift: std_logic;
signal left : unsigned(8 downto 0); -- left operand
signal right : unsigned(8 downto 0); -- right operand
signal valu_res: unsigned(8 downto 0); -- result (mult_res8 or valu_res)
signal mult_right: unsigned(15 downto 0); -- right multiplication operand
signal mult_left: unsigned(15 downto 0); -- left multiplication operand
signal mult_res32: unsigned(31 downto 0); -- multiplication result
signal mult_res8: unsigned(7 downto 0); -- shift value for result shift register (multiplication)
signal output: unsigned(32 downto 0); -- result shift register
signal input : unsigned (8 downto 0); -- shift value for result shift register (other operations)
begin
carry <= carry_in when (carry_sel = "00") else
output(32) when (carry_sel = "01") else
'0';
rshift <= rshift_in when (carry_sel = "00") else
output(32) when (carry_sel = "01") else
'0';
left <= unsigned('0' & v_in(7 downto 0)) when (source_sel) = "00" else
unsigned('0' & v_in(15 downto 8)) when (source_sel) = "01" else
unsigned('0' & v_in(23 downto 16)) when (source_sel) = "10" else
unsigned('0' & v_in(31 downto 24));
right <= unsigned('0' & w_in(7 downto 0)) when (source_sel) = "00" else
unsigned('0' & w_in(15 downto 8)) when (source_sel) = "01" else
unsigned('0' & w_in(23 downto 16)) when (source_sel) = "10" else
unsigned('0' & w_in(31 downto 24));
-- execute all other operations
valu_res <= left + right + carry when (valuop = "0000") else
left - right - carry when (valuop = "0010") else
left(7 downto 0) & carry when (valuop = "1100") else
left(0) & rshift & left(7 downto 1) when (valuop = "1110") else
unsigned( std_logic_vector(left) and std_logic_vector(right)) when (valuop = "1000") else
unsigned( std_logic_vector(left) or std_logic_vector(right)) when (valuop = "1001") else
unsigned( std_logic_vector(left) xor std_logic_vector(right));
mult_gen: if use_vector_mult generate
-- operands for multiplication
mult_left <= unsigned("00000000" & v_in(7 downto 0)) when mult_source_sel = "00" else
unsigned("00000000" & v_in(23 downto 16)) when mult_source_sel = "01" else
unsigned(v_in(15 downto 0));
mult_right <= unsigned("00000000" & w_in(7 downto 0)) when mult_source_sel = "00" else
unsigned("00000000" & w_in(23 downto 16)) when mult_source_sel = "01" else
unsigned(w_in(15 downto 0));
-- execute multiplication
mult_res32 <= mult_left * mult_right;
mult_res8 <= mult_res32(7 downto 0) when mult_dest_sel = "00" else
mult_res32(15 downto 8) when mult_dest_sel = "01" else
mult_res32(23 downto 16) when mult_dest_sel = "10" else
mult_res32(31 downto 24);
end generate;
not_mult_gen: if not use_vector_mult generate
mult_res8 <= "00000000";
end generate;
-- use result from other operation or multiplication?
input <= valu_res when reg_input_sel = '0' else "0" & mult_res8;
-- output register
process
begin
wait until clk ='1' and clk'event;
if load_other = '1' then
-- shift from right to left
output(32 downto 24) <= input(8 downto 0);
output(23 downto 0) <= output(31 downto 8);
else
if load_lsr = '1' then
-- shift from left to right
output(7 downto 0) <= input(7 downto 0);
output(32) <= input(8);
output(31 downto 8) <= output(23 downto 0);
else
output <= output;
end if;
end if;
end process;
valu_out <= std_logic_vector(output(31 downto 0));
carry_out <= output(32);
end rtl;
 
 
 
/branches/avendor/cpu/units/flag.vhd
0,0 → 1,43
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: flag
--
-- PURPOSE: one bit flag for status register
-- carry or zero
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity flag is
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic;
data_out: out std_logic
);
end flag;
 
architecture rtl of flag is
signal q: std_logic;
begin
process
begin
wait until clk='1' and clk'event;
if load = '1' then
q <= data_in;
else
q <= q;
end if;
 
end process;
data_out <= q;
end rtl;
 
/branches/avendor/cpu/units/rs232.vhd
0,0 → 1,259
----------------------------------------------------------------------------------
 
 
--
-- Create Date: 23:34:55 02/27/2007
-- Design Name:
-- Module Name: rs232 - Behavioral
-- Project Name:
-- Target Devices: Xilinx
-- Tool versions:
-- Description: This module provides RS232 communication
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity rs232 is
generic(DATABITS: integer:= 8;
STARTBITS: integer:= 1;
STOPBITS: integer:= 1
);
port( -- HW signalling
CLK_50MHZ : in std_logic;
RS232_RXD: in std_logic;
RS232_TXD: out std_logic := '1';
-- internal DataCom
DATA_TX : in std_logic_vector(DATABITS-1 downto 0);
TX_SEND_DATA : in std_logic;
TX_BUSY : out std_logic := '0';
DATA_RX : out std_logic_vector(DATABITS-1 downto 0) := (others => '0');
RX_DATA_RCVD : out std_logic := '0';
RX_BUSY : out std_logic := '0'
);
end rs232;
 
 
 
architecture Behavioral of rs232 is
 
type SER_STATES is (IDLE, SYN, B0, B1, B2, B3, B4, B5, B6, B7, VALID);
 
signal SER_STATE: SER_STATES := IDLE;
 
 
signal CLK_38400: std_logic := '0';
signal SIG_RST_TSER2: std_logic := '0';
signal SIG_TSER2: std_logic := '0';
 
signal SIG_RST_TSER: std_logic := '0';
signal SIG_TSER: std_logic := '0';
 
 
begin
 
 
 
-- Generate Signal for Serial Clock at 38400
P_GEN_CLK38400: process (CLK_50MHZ)
-- 1302 == 10100010110
constant CLK38400_MAX: std_logic_vector(10 downto 0) := "10100010110";
variable CLK38400_CUR: std_logic_vector(10 downto 0) := "00000000000";
begin
if CLK_50MHZ'event AND CLK_50MHZ='1' then
if CLK38400_CUR = CLK38400_MAX then
CLK38400_CUR := (others => '0');
CLK_38400 <= '1';
else
CLK38400_CUR := CLK38400_CUR + "00000000001";
CLK_38400 <= '0';
end if;
end if;
end process P_GEN_CLK38400;
 
 
 
-- Generate Reset-driven Signal after Tser/2
P_GEN_SIG_TSER2: process (CLK_50MHZ)
-- 651 == 1010001011
constant TSER2_MAX: std_logic_vector(9 downto 0) := "1010001011";
variable TSER2_CUR: std_logic_vector(9 downto 0) := "0000000000";
begin
if CLK_50MHZ'event AND CLK_50MHZ='1' then
if SIG_RST_TSER2 = '1' then
SIG_TSER2 <= '0';
TSER2_CUR := (others => '0');
elsif TSER2_CUR = TSER2_MAX then
SIG_TSER2 <= '1';
TSER2_CUR := (others => '0');
else
SIG_TSER2 <= '0';
TSER2_CUR := TSER2_CUR + "0000000001";
end if;
end if;
end process P_GEN_SIG_TSER2;
 
 
 
-- Generate Reset-driven Signal after Tser
P_GEN_SIG_TSER: process (CLK_50MHZ)
constant TSER_MAX: std_logic_vector(10 downto 0) := "10100010110";
variable TSER_CUR: std_logic_vector(10 downto 0) := "00000000000";
begin
if CLK_50MHZ'event AND CLK_50MHZ='1' then
if SIG_RST_TSER = '1' then
SIG_TSER <= '0';
TSER_CUR := (others => '0');
elsif TSER_CUR = TSER_MAX then
SIG_TSER <= '1';
TSER_CUR := (others => '0');
else
SIG_TSER <= '0';
TSER_CUR := TSER_CUR + "00000000001";
end if;
end if;
end process P_GEN_SIG_TSER;
 
 
 
-- RX / TX Process
P_RX_TX: process (CLK_50MHZ)
constant TOKENSIZE: integer:= STARTBITS + DATABITS + STOPBITS;
 
-- variables for RX
variable BYTE_RX: std_logic_vector(7 downto 0);
-- for testing
variable signcount: std_logic_vector(3 downto 0) := "0000";
 
-- variables for TX
variable SEND_TOKEN: std_logic := '0';
variable TOKEN_OUT: std_logic_vector(TOKENSIZE-1 downto 0);
variable COUNT: std_logic_vector(3 downto 0) := "0000";
 
begin
if CLK_50MHZ'event AND CLK_50MHZ='1' then
-- RX
RX_BUSY <= '1';
case SER_STATE is
when IDLE => if RS232_RXD = '0' then
SIG_RST_TSER2 <= '1';
SER_STATE <= SYN;
RX_DATA_RCVD <= '0';
else
RX_BUSY <= '0';
SIG_RST_TSER2 <= '0';
SER_STATE <= IDLE;
RX_DATA_RCVD <= '0';
end if;
when SYN => if SIG_TSER2 = '1' then
SIG_RST_TSER2 <= '0';
SIG_RST_TSER <= '1';
SER_STATE <= B0;
else
SIG_RST_TSER2 <= '0';
SIG_RST_TSER <= '0';
SER_STATE <= SYN;
end if;
when B0 => if SIG_TSER = '1' then
SIG_RST_TSER <= '0';
SER_STATE <= B1;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else
SIG_RST_TSER <= '0';
SER_STATE <= B0;
end if;
when B1 => if SIG_TSER = '1' then
SER_STATE <= B2;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B1;
end if;
when B2 => if SIG_TSER = '1' then
SER_STATE <= B3;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B2;
end if;
when B3 => if SIG_TSER = '1' then
SER_STATE <= B4;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B3;
end if;
when B4 => if SIG_TSER = '1' then
SER_STATE <= B5;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B4;
end if;
when B5 => if SIG_TSER = '1' then
SER_STATE <= B6;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B5;
end if;
when B6 => if SIG_TSER = '1' then
SER_STATE <= B7;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B6;
end if;
when B7 => if SIG_TSER = '1' then
SER_STATE <= VALID;
BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
else SER_STATE <= B7;
end if;
when VALID => if SIG_TSER = '1' then
if RS232_RXD = '1' then
DATA_RX <= BYTE_RX;
RX_DATA_RCVD <= '1';
else
DATA_RX <= (others => '0');
RX_DATA_RCVD <= '0';
end if;
SER_STATE <= IDLE;
else
SER_STATE <= VALID;
end if;
end case;
 
-- TX
TX_BUSY <= '0';
if TX_SEND_DATA = '1' AND SEND_TOKEN = '0' then
TOKEN_OUT := '1' & DATA_TX & '0';
SEND_TOKEN := '1';
end if;
if SEND_TOKEN = '1' then
TX_BUSY <= '1';
if CLK_38400 = '1' then
if COUNT < TOKENSIZE then
--TX_BUSY <= '1';
COUNT := COUNT + "0001";
-- send from right to left (LSB first)
RS232_TXD <= TOKEN_OUT(0);
TOKEN_OUT(TOKENSIZE-1 downto 0) := TOKEN_OUT(0) & TOKEN_OUT(TOKENSIZE-1 downto 1);
else
COUNT := "0000";
SEND_TOKEN := '0';
--TX_BUSY <= '0';
end if;
end if;
--else
--TX_BUSY <= '0';
end if;
end if;
end process P_RX_TX;
 
end Behavioral;
/branches/avendor/cpu/units/dataregister.vhd
0,0 → 1,41
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: dataregister
--
-- PURPOSE: single dataregister of scalar unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity dataregister is
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end dataregister;
 
architecture rtl of dataregister is
signal data_out_buffer: unsigned(31 downto 0);
begin
process
begin
wait until clk='1' and clk'event;
if load = '1' then
data_out_buffer <= unsigned(data_in);
else
data_out_buffer <= data_out_buffer;
end if;
end process;
data_out <= std_logic_vector(data_out_buffer);
end rtl;
 
/branches/avendor/cpu/units/selectunit.vhd
0,0 → 1,35
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: selectunit
--
-- PURPOSE: selects one word out of a vector
-- register
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity selectunit is
port (
data_in : in vectordata_type;
k_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end selectunit;
 
architecture rtl of selectunit is
signal index: integer range 0 to k-1;
begin
index <= conv_integer(k_in) when (k_in < k) else 0;
data_out <= data_in(index);
end rtl;
/branches/avendor/cpu/units/controlunit.vhd
0,0 → 1,435
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: controlunit
--
-- PURPOSE: controlunit of scalar unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity controlunit is
port(
-- clock
clk: in std_logic; -- clock signal
-- instruction in
ir: in std_logic_vector(31 downto 0); -- instruction
-- control signals in
reset_cpu: in std_logic; -- reset signal
zero: in std_logic; -- zero flag
carry: in std_logic; -- carry flag
ready: in std_logic; -- memory interface ready signal
-- control signals out
access_type: out std_logic_vector(2 downto 0); -- memory interface access type (we, oe, cs)
c0: out std_logic; -- c0 signal
c1: out std_logic; -- c1 signal
cc2: out std_logic_vector(1 downto 0); -- cc2 signal
--c3: out std_logic; -- c3 signal => obsolete
cc4: out std_logic_vector(1 downto 0); -- cc4 signal
cc5: out std_logic_vector(1 downto 0); -- cc5 signal
c6: out std_logic; -- c6 signal
c7: out std_logic; -- c7 signal
c8: out std_logic; -- c7 signal
load_ir: out std_logic; -- instruction register load signal
inc_ic: out std_logic; -- instruction counter increment signal
load_ic: out std_logic; -- instruction counter load signal
load_c: out std_logic; -- carry flag load signal
load_z: out std_logic; -- zero flag load signal
-- communication with vecor unit
ir_ready: out std_logic; -- next instruction has been loaded into ir
s_ready: out std_logic; -- data from scalar unit or mi is ready
s_fetched: out std_logic; -- signal for vector unit to continue
 
v_ready: in std_logic; -- data for scalar unit or mi is ready
v_fetched: in std_logic; -- signal for scalar unit to continue
v_done: in std_logic; -- vector unit completed command
halted: out std_logic -- enabled when cpu is in halt state
);
end controlunit;
 
architecture rtl of controlunit is
type statetype is (if1, if2, decode_wait, ld1, ld2, vld1, vld2, vld3, vld4,
st1, st2, vst1, vst2, vst3, smv1, smv2, vms1, vms2, nop, jal, jcc, alu, flag, sync, halt,
mova1, mova2, reset);
signal state : statetype := halt;
signal nextstate : statetype := halt;
 
begin
 
-- state register
process
begin
wait until clk='1' and clk'event;
state <= nextstate;
end process;
-- state transitions
process (state, ready, reset_cpu, ir, carry, zero, v_ready, v_fetched, v_done)
begin
-- avoid latches
access_type <= "000";
c0 <= '0';
c1 <= '0';
cc2 <= "00";
cc4 <= "00";
cc5 <= "00";
c6 <= '0';
c7 <= '0';
c8 <= '0';
load_ir <= '0';
inc_ic <= '0';
load_ic <= '0';
load_c <= '0';
load_z <= '0';
ir_ready <= '0';
s_ready <= '0';
s_fetched <= '0';
nextstate <= reset;
halted <= '0';
if reset_cpu = '1' then
nextstate <= reset;
else
case state is
-- RESET STATE --
when reset =>
cc4 <= "10";
cc5 <= "10";
load_c <= '1';
load_z <= '1';
nextstate <= if1;
-- INSTRUCTION FETCH STATE 1 --
when if1 =>
access_type <= "010";
nextstate <= if2;
-- INSTRUCTION FETCH STATE 2 --
when if2 =>
access_type <= "010";
ir_ready <= '1';
load_ir <= '1';
if ready = '0' then
nextstate <= if2;
else
nextstate <= decode_wait;
end if;
-- DECODE AND WAIT STATE --
when decode_wait =>
if ir(31 downto 28) = "1000" then -- ld
if ready = '1' then
nextstate <= ld1;
else
nextstate <= decode_wait;
end if;
elsif ir(31 downto 28) = "1001" then -- vld
if ready = '1' then
nextstate <= vld1;
else
nextstate <= decode_wait;
end if;
elsif ir(31 downto 28) = "1010" then -- store
if ready = '1' then
nextstate <= st1;
else
nextstate <= decode_wait;
end if;
elsif ir(31 downto 26) = "101100" then -- vst
if ready = '1' and v_ready = '1' then
nextstate <= vst1;
else
nextstate <= decode_wait;
end if;
elsif ir(31 downto 26) = "101101" then -- mova
nextstate <= mova1;
elsif ir(31 downto 26) = "101110" then -- mov r(t), s
nextstate <= smv1;
elsif ir(31 downto 26) = "101111" then -- mov d, v(t)
nextstate <= vms1;
else
case ir(31 downto 30) is
when "00" =>
if ir(29) = '0' then -- nop
nextstate <= nop;
elsif ir(29 downto 27) = "101" then -- halt
report "HALT";
nextstate <= halt;
elsif ir(29 downto 26) = "1000" then -- jmp, jal
nextstate <= jal;
elsif ir(29 downto 28) = "11" then -- jcc
nextstate <= jcc;
end if;
when "01" => -- alu cmd
nextstate <= alu;
when "11" => -- set/clear flags
nextstate <= flag;
when others => -- error
nextstate <= halt;
end case;
end if;
-- LOAD STATE 1 --
when ld1 =>
access_type <= "010";
c1 <= '1';
c7 <= '1';
nextstate <= ld2;
-- LOAD STATE 2 --
when ld2 =>
access_type <= "010";
report "LD";
c0 <= '1';
c6 <= '1';
c7 <= '1';
c8 <= '1';
load_z <= '1';
inc_ic <= '1';
if ready = '0' then
nextstate <= ld2;
else
nextstate <= sync;
end if;
-- VECTOR LOAD STATE 1 --
when vld1 =>
access_type <= "011";
c1 <= '1';
c7 <= '1';
if ready = '1' then
nextstate <= vld1;
else
nextstate <= vld2;
end if;
-- VECTOR LOAD STATE 2 --
when vld2 =>
access_type <= "011";
c1 <= '1';
c7 <= '1';
if ready = '1' then
nextstate <= vld3;
else
nextstate <= vld2;
end if;
-- VECTOR LOAD STATE 3 --
when vld3 =>
access_type <= "011";
c1 <= '1';
c7 <= '1';
s_ready <= '1';
if v_fetched = '1' then
nextstate <= vld4;
else
nextstate <= vld3;
end if;
-- VECTOR LOAD STATE 4 --
when vld4 =>
report "VLD";
inc_ic <= '1';
nextstate <= sync;
-- STORE STATE 1 --
when st1 =>
access_type <= "100";
c1 <= '1';
c7 <= '1';
inc_ic <= '1';
nextstate <= st2;
-- STORE STATE 2 --
when st2 =>
access_type <= "100";
c1 <= '1';
c7 <= '1';
if ready = '0' then
nextstate <= st2;
else
nextstate <= sync;
end if;
-- VECTOR STORE STATE 1 --
when vst1 =>
access_type <= "101";
c1 <= '1';
c7 <= '1';
if ready = '1' then
nextstate <= vst1;
else
nextstate <= vst2;
end if;
-- VECTOR STORE STATE 2 --
when vst2 =>
access_type <= "101";
c1 <= '1';
c7 <= '1';
if ready = '1' then
nextstate <= vst3;
else
nextstate <= vst2;
end if;
-- VECTOR STORE STATE 3 --
when vst3 =>
report "VST";
s_fetched <= '1';
inc_ic <= '1';
nextstate <= sync;
-- SCALAR MOVE TO VECTOR STATE 1 --
when smv1 =>
s_ready <= '1';
if v_fetched = '1' then
nextstate <= smv2;
else
nextstate <= smv1;
end if;
-- SCALAR MOVE TO VECTOR STATE 2 --
when smv2 =>
report "MOV R(T), S";
inc_ic <= '1';
nextstate <= sync;
-- MOVA STATE 1 --
when mova1 =>
s_ready <= '1';
if v_fetched = '1' then
nextstate <= mova2;
else
nextstate <= mova1;
end if;
-- MOVA STATE 2 --
when mova2 =>
report "MOVA";
inc_ic <= '1';
nextstate <= sync;
-- VECTOR MOVE TO SCALAR STATE --
when vms1 =>
if v_ready = '1' then
nextstate <= vms2;
else
nextstate <= vms1;
end if;
-- VECTOR MOVE TO SCALAR STATE 2 --
when vms2 =>
report "MOV D, V(T)";
cc2 <= "10";
c6 <= '1';
s_fetched <= '1';
inc_ic <= '1';
nextstate <= sync;
-- NOP STATE --
when nop =>
report "NOP";
inc_ic <= '1';
nextstate <= sync;
-- JUMP AND LINK STATE
when jal =>
report "JMP, JAL";
c7 <= '1';
load_ic <= '1';
cc2 <= "01";
c6 <= '1';
nextstate <= sync;
-- JUMP CONDITIONAL STATE
when jcc =>
report "JCC";
if (ir(27) = '0' and ir(26) = carry)
or (ir(27) = '1' and ir(26) = zero) then
c7 <= '1';
load_ic <= '1';
else
inc_ic <= '1';
end if;
nextstate <= sync;
-- ALU COMMAND STATE --
when alu =>
report "ALU COMMANDS";
load_c <= '1';
load_z <= '1';
c6 <= '1';
inc_ic <= '1';
nextstate <= sync;
-- SET/CLEAR FLAGS STATE --
when flag =>
report "SET/RESET FLAGS";
load_z <= ir(23);
load_c <= ir(22);
cc4 <= '1' & ir(21);
cc5 <= '1' & ir(20);
inc_ic <= '1';
nextstate <= sync;
-- SYNC STATE --
when sync =>
if v_done = '1' then
nextstate <= if1;
else
nextstate <= sync;
end if;
-- HALT STATE --
when halt =>
report "halted";
halted <= '1';
nextstate <= halt;
end case;
end if;
end process;
end rtl;
 
/branches/avendor/cpu/units/demultiplexer1x4.vhd
0,0 → 1,35
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: demultiplexer1x4
--
-- PURPOSE: demultiplexer, one input, four outputs
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity demultiplexer1x4 is
port( selector: in std_logic_vector(1 downto 0);
data_in: in std_logic;
data_out_00: out std_logic;
data_out_01: out std_logic;
data_out_10: out std_logic;
data_out_11: out std_logic
);
end demultiplexer1x4;
 
architecture rtl of demultiplexer1x4 is
begin
data_out_00 <= data_in when selector = "00" else '0';
data_out_01 <= data_in when selector = "01" else '0';
data_out_10 <= data_in when selector = "10" else '0';
data_out_11 <= data_in when selector = "11" else '0';
end rtl;
 
/branches/avendor/cpu/units/alu.vhd
0,0 → 1,131
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: alu
--
-- PURPOSE: alu of scalar unit
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
use work.cfg.all;
 
entity alu is
port(
a_in: in std_logic_vector(31 downto 0);
b_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
aluop: in std_logic_vector(3 downto 0);
op_select: in std_logic;
zero_out: out std_logic;
carry_out: out std_logic;
alu_out: out std_logic_vector(31 downto 0)
);
end alu;
 
architecture rtl of alu is
component multiplexer2
generic (
w : positive
);
port (
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
for mux: multiplexer2 use entity work.multiplexer2(rtl);
signal aluop_multiplexed: std_logic_vector(3 downto 0) := "0000";
signal left: unsigned(32 downto 0);
signal right: unsigned(32 downto 0);
signal mult_res: unsigned(31 downto 0);
signal carry: std_logic;
begin
mux: multiplexer2
generic map (w => 4)
port map (selector => op_select, data_in_0 => aluop, data_in_1 => "0000",
data_out => aluop_multiplexed);
process (a_in, b_in, carry, left, right, aluop_multiplexed, mult_res)
variable alu_out_buffer: unsigned(32 downto 0);
begin
case aluop_multiplexed is
when "0000" | "0001" | "0100" => -- add / adc / inc - use same adder
alu_out_buffer := left + right + carry;
when "0010" | "0011" | "0110" => -- sub / sbc / dec - use same subtractor
alu_out_buffer := left - right - carry;
when "1000" => -- and (a and b)
alu_out_buffer := "0" & unsigned( a_in and b_in);
when "1001" => -- or (a or b)
alu_out_buffer := "0" & unsigned(a_in or b_in);
when "1010" => -- xor (a xor b)
alu_out_buffer := "0" & unsigned(a_in xor b_in);
when "1011" => -- mult (a(15:0) * b(15:0)
alu_out_buffer := "0" & mult_res;
when "1100" => -- lsl (a shift left, insert 0)
alu_out_buffer(32 downto 1) := left(31 downto 0);
alu_out_buffer(0) := '0';
when "1110" => -- lsr (a shift right, insert 0)
alu_out_buffer(32) := left(0);
alu_out_buffer(30 downto 0) := left(31 downto 1);
alu_out_buffer(31) := '0';
when "1101" => -- rol (a shift left, insert c)
alu_out_buffer(32 downto 1) := left(31 downto 0);
alu_out_buffer(0) := carry;
when "1111" => -- ror (a shift right, insert c)
alu_out_buffer(32) := left(0);
alu_out_buffer(30 downto 0) := left(31 downto 1);
alu_out_buffer(31) := carry;
when others => -- not defined
alu_out_buffer := (others => '0');
end case;
alu_out <= std_logic_vector(alu_out_buffer(31 downto 0));
carry_out <= alu_out_buffer(32);
if(alu_out_buffer(31 downto 0) = 0) then
zero_out <= '1';
else
zero_out <= '0';
end if;
end process;
left <= unsigned ("0" & a_in);
right <= (others => '0') when (aluop_multiplexed = "0100" or aluop_multiplexed = "0110")
else unsigned ("0" & b_in);
carry <= '0' when (aluop_multiplexed = "0000" or aluop_multiplexed = "0010")
else '1' when (aluop_multiplexed = "0100" or aluop_multiplexed = "0110")
else carry_in;
 
mult_gen: if use_scalar_mult generate
mult_res <= left(15 downto 0) * right(15 downto 0);
end generate;
not_mult_gen: if not use_scalar_mult generate
mult_res <= (others => '0');
end generate;
end rtl;
 
/branches/avendor/cpu/units/instructioncounter.vhd
0,0 → 1,54
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: instructioncounter
--
-- PURPOSE: instruction counter
-- basically a 32 bit register with increment
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity instructioncounter is
port( clk: in std_logic;
load: in std_logic;
inc: in std_logic;
reset: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end instructioncounter;
 
architecture rtl of instructioncounter is
signal data_out_buffer: unsigned(31 downto 0);
begin
process
begin
wait until clk='1' and clk'event;
if reset = '1' then
data_out_buffer <= "00000000000000000000000000000000";
else
if load = '1' and inc = '0' then
data_out_buffer <= unsigned(data_in);
end if;
if load = '0' and inc = '1' then
data_out_buffer <= data_out_buffer + inc;
end if;
if (load = inc) then
data_out_buffer <= data_out_buffer;
end if;
end if;
end process;
data_out <= std_logic_vector(data_out_buffer);
end rtl;
 
/branches/avendor/cpu/units/debugger.vhd
0,0 → 1,808
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: debugger
--
-- PURPOSE: debugger for clvp
-- controls cpu via rs232
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity debugger is
port (
clk_in: in std_logic; -- use 50mhz for rs232 timing
clk_cpu: out std_logic;
clk_mem: out std_logic;
reset_out: out std_logic;
rs232_txd: out std_logic;
rs232_rxd: in std_logic;
a: in std_logic_vector(31 downto 0);
x: in std_logic_vector(31 downto 0);
y: in std_logic_vector(31 downto 0);
ir: in std_logic_vector(31 downto 0);
ic: in std_logic_vector(31 downto 0);
mem_switch: out std_logic;
mem_ready: in std_logic;
mem_access: in std_logic_vector(2 downto 0);
mem_access_dbg: out std_logic_vector(2 downto 0);
mem_addr: in std_logic_vector(31 downto 0);
mem_addr_dbg: out std_logic_vector(31 downto 0);
mem_data: in std_logic_vector(31 downto 0);
mem_data_dbg: out std_logic_vector(31 downto 0);
carry: in std_logic;
zero: in std_logic;
ir_ready: in std_logic;
halted: in std_logic
);
end debugger;
 
architecture rtl of debugger is
 
generic( DATABITS: integer:= 8;
STARTBITS: integer:= 1;
STOPBITS: integer:= 1
);
port( CLK_50MHZ : in std_logic;
RS232_RXD : in std_logic;
RS232_TXD : out std_logic;
DATA_TX : in std_logic_vector(DATABITS-1 downto 0);
TX_SEND_DATA : in std_logic;
TX_BUSY : out std_logic;
DATA_RX : out std_logic_vector(DATABITS-1 downto 0);
RX_DATA_RCVD : out std_logic;
RX_BUSY : out std_logic
);
end component;
component bufg
port (
i: in std_logic;
o: out std_logic
);
end component;
for rs232_impl: rs232 use entity work.rs232(Behavioral);
signal data_tx: std_logic_vector(7 downto 0);
signal data_rx: std_logic_vector(7 downto 0);
signal tx_busy: std_logic;
signal rx_busy: std_logic;
signal data_received: std_logic;
signal send_data: std_logic;
signal clk_buffer_cpu, clk_buffer_mem: std_logic;
-- statemachine debugger
type statetype is (waiting, decode, clock, reset1, reset2, flags, rega, regx,
regy, regir, regic, busy8, init8, sending8, busy32, init32, sending32, inc32, echo,
ma, md, go, pause, to_fetch_address, to_fetch_data, fetch_address, fetch_data, to_normal,
mem_read1, mem_read2, mem_read3,mem_read4, mem_write1, mem_write2, mem_write3, mem_write4,
mem_restore1, mem_restore2, mem_restore3, mem_restore4, send_checksum, startcc, stopcc,
ccstatus, getcc);
signal state : statetype := waiting;
signal nextstate : statetype := waiting;
-- statemachine clock logic
type clocktype is (high, low, freehigh, freelow, memorylow, memoryhigh, ccountstart, ccountlow, ccounthigh);
signal clockstate : clocktype := low;
signal nextclockstate : clocktype := low;
 
signal counter : std_logic_vector(1 downto 0) := "00";
signal inc: std_logic;
signal clockcounter : std_logic_vector(31 downto 0) := (others => '0');
signal clockcounter_inc, clockcounter_res : std_logic;
signal in_buffer: std_logic_vector(31 downto 0);
signal out_buffer: std_logic_vector(31 downto 0) := (others => '0');
signal ar: std_logic_vector(31 downto 0) := (others => '0');
signal ar_shift: std_logic;
signal dr: std_logic_vector(31 downto 0) := (others => '0');
signal dr_shift: std_logic;
signal load, load_mem_data: std_logic;
signal tofree, todebug, tomemory, clocktick : std_logic;
signal startclockcount, stopclockcount, clockcountstatus : std_logic;
signal status: std_logic_vector(1 downto 0) := (others => '0');
signal st_input: std_logic_vector(1 downto 0);
signal st_set: std_logic;
signal checksum : std_logic_vector(7 downto 0);
begin
rs232_impl: rs232
generic map (DATABITS => 8, STARTBITS => 1, STOPBITS => 1)
port map (
CLK_50MHZ => clk_in, RS232_RXD => rs232_rxd, RS232_TXD => rs232_txd,
DATA_TX => data_tx, TX_SEND_DATA => send_data, TX_BUSY => tx_busy,
DATA_RX => data_rx, RX_DATA_RCVD => data_received, RX_BUSY => rx_busy
);
gbuf_for_clk_cpu: bufg
port map (
i => clk_buffer_cpu,
o => clk_cpu
);
gbuf_for_clk_mem: bufg
port map (
i => clk_buffer_mem,
o => clk_mem
);
-- counter
process
begin
wait until clk_in='1' and clk_in'event;
counter <= counter;
clockcounter <= clockcounter;
if inc = '1' then
counter <= counter + '1';
end if;
if clockcounter_inc = '1' then
clockcounter <= clockcounter +1;
else
if clockcounter_res = '1' then
clockcounter <= (others => '0');
end if;
end if;
 
end process;
-- register
process
begin
wait until clk_in='1' and clk_in'event;
out_buffer <= out_buffer;
status <= status;
ar <= ar;
dr <= dr;
if load = '1' then
out_buffer <= in_buffer;
else
if load_mem_data = '1' then
out_buffer <= mem_data;
end if;
end if;
if ar_shift = '1' then
ar(31 downto 8) <= ar(23 downto 0);
ar(7 downto 0) <= data_rx;
end if;
if dr_shift = '1' then
dr(31 downto 8) <= dr(23 downto 0);
dr(7 downto 0) <= data_rx;
end if;
if st_set = '1' then
status <= st_input;
end if;
end process;
mem_addr_dbg <= ar;
mem_data_dbg <= dr;
checksum <= out_buffer(31 downto 24) xor out_buffer(23 downto 16)
xor out_buffer(15 downto 8) xor out_buffer(7 downto 0);
-- state register
process
begin
wait until clk_in='1' and clk_in'event;
state <= nextstate;
clockstate <= nextclockstate;
end process;
-- clock state machine
process (clockstate, tofree, todebug, tomemory, clocktick, clockcounter_inc, clockcounter_res, clockcounter, ic,
startclockcount, stopclockcount, ar)
begin
-- avoid latches
clk_buffer_cpu <= '0';
clk_buffer_mem <= '0';
clockcountstatus <= '1';
clockcounter_inc <= '0';
clockcounter_res <= '0';
case clockstate is
-- CLOCK COUNTING STATES --
when ccountstart => -- start clock counting
clockcounter_inc <= '0';
clockcounter_res <= '1';
clockcountstatus <= '0';
nextclockstate <= ccountlow;
when ccountlow => -- generate clock low signal
clockcountstatus <= '0';
clk_buffer_cpu <= '0';
clk_buffer_mem <= '0';
if stopclockcount = '1' then
nextclockstate <= low;
else
if ic = ar then -- stop when instruction counter value matches given address
nextclockstate <= low;
else
nextclockstate <= ccounthigh;
end if;
end if;
when ccounthigh => -- generate clock high signal
clockcountstatus <= '0';
clockcounter_inc <= '1';
clk_buffer_cpu <= '1';
clk_buffer_mem <= '1';
if stopclockcount = '1' then
nextclockstate <= low;
else
nextclockstate <= ccountlow;
end if;
-- DEBUG MODE STATES --
when low => -- generate clock low signal
clk_buffer_cpu <= '0';
clk_buffer_mem <= '0';
if startclockcount = '1' then -- only allow to start clockcount from debug mode
nextclockstate <= ccountstart;
else
if tomemory = '1' then
nextclockstate <= memorylow;
else
if tofree = '1' then
nextclockstate <= freelow;
else
if clocktick = '1' then
nextclockstate <= high;
else
nextclockstate <= low;
end if;
end if;
end if;
end if;
when high => -- generate clock high signal
clk_buffer_cpu <= '1';
clk_buffer_mem <= '1';
if tomemory = '1' then
nextclockstate <= memorylow;
else
if tofree = '1' then
nextclockstate <= freelow;
else
nextclockstate <= low;
end if;
end if;
-- FREE RUNNING MODE STATES --
when freelow => -- generate clock low signal
clk_buffer_cpu <= '0';
clk_buffer_mem <= '0';
if tomemory = '1' then
nextclockstate <= memorylow;
else
if todebug = '1' then
nextclockstate <= low;
else
nextclockstate <= freehigh;
end if;
end if;
when freehigh => -- generate clock high signal
clk_buffer_cpu <= '1';
clk_buffer_mem <= '1';
if tomemory = '1' then
nextclockstate <= memorylow;
else
if todebug = '1' then
nextclockstate <= low;
else
nextclockstate <= freelow;
end if;
end if;
-- CLOCK MEMORY ONLY STATES --
when memorylow => -- generate memory clock low signal
clk_buffer_mem <= '0';
if todebug = '1' then
nextclockstate <= low;
else
nextclockstate <= memoryhigh;
end if;
when memoryhigh => -- generate memory clock high signal
clk_buffer_mem <= '1';
if todebug = '1' then
nextclockstate <= low;
else
nextclockstate <= memorylow;
end if;
end case;
end process;
-- debugger state machine
process (clk_in, data_rx, a, x, y, ir, ic, carry, zero, ir_ready, tx_busy, data_received, counter,
state, out_buffer, mem_addr, mem_data, mem_access, mem_ready, halted, status, checksum,
clockcountstatus, clockcounter )
begin
-- avoid latches
reset_out <= '0';
send_data <= '0';
data_tx <= (others => '0');
in_buffer <= (others => '0');
nextstate <= waiting;
inc <= '0';
load <= '0';
tofree <= '0';
todebug <= '0';
tomemory <= '0';
clocktick <= '0';
ar_shift <= '0';
dr_shift <= '0';
st_input <= (others => '0');
st_set <= '0';
mem_switch <= '0';
mem_access_dbg <= "000";
load_mem_data <= '0';
startclockcount <= '0';
stopclockcount <= '0';
case state is
-- WAIT FOR COMMANDS / DATA --
when waiting =>
if data_received = '1' then
nextstate <= decode;
else
nextstate <= waiting;
end if;
-- DECODE STATE --
when decode =>
case status is
when "00" => -- normal modus
case data_rx is
when "01100011" | "01000011" => -- c/C = clock
nextstate <= clock;
when "01110010" | "01010010" => -- r/R = reset
nextstate <= reset1;
when "01100110" | "01000110" => -- f/F = flags
nextstate <= flags;
when "01100001" | "01000001" => -- a/A = register a
nextstate <= rega;
when "01111000" | "01011000" => -- x/X = register x
nextstate <= regx;
when "01111001" | "01011001" => -- y/Y = register y
nextstate <= regy;
when "01101001" | "01001001" => -- i/I = instruction register
nextstate <= regir;
when "01101010" | "01001010" => -- j/J = instruction counter
nextstate <= regic;
when "01101101" | "01001101" => -- m/M = memory data
nextstate <= md;
when "01101110" | "01001110" => -- n/N = memory address
nextstate <= ma;
when "01100111" | "01000111" => -- g/G = enter free-running-mode
nextstate <= go;
when "01110000" | "01010000" => -- p/P = leave free-running-mode
nextstate <= pause;
when "00110000" => -- 0 = fetch address
nextstate <= to_fetch_address;
when "00110001" => -- 1 = fetch data
nextstate <= to_fetch_data;
when "00110010" => -- 2 = read from memory
nextstate <= mem_read1;
when "00110011" => -- 3 = write to memory
nextstate <= mem_write1;
when "00110100" => -- 4 = enter clock count mode
nextstate <= startcc;
when "00110101" => -- 5 = stop clock count mode
nextstate <= stopcc;
when "00110110" => -- 6 = clock count status
nextstate <= ccstatus;
when "00110111" => -- 7 = get clock counter
nextstate <= getcc;
when others => -- unknown command, echo
nextstate <= echo;
end case;
when "01" => -- receiving memory write command
nextstate <= fetch_address;
when "10" => -- receiving memory read command
nextstate <= fetch_data;
when others =>
nextstate <= to_normal;
end case;
-- CLOCKCOUNTER STATS --
when startcc => -- start clock counter
startclockcount <= '1';
nextstate <= echo;
when stopcc => -- stop clock counter
stopclockcount <= '1';
nextstate <= echo;
when ccstatus => -- get status of clock counter
in_buffer(7 downto 1) <= (others => '0');
in_buffer(0) <= clockcountstatus;
load <= '1';
nextstate <= busy8;
when getcc => -- get clockcounter value
in_buffer(31 downto 0) <= clockcounter;
load <= '1';
nextstate <= busy32;
-- READ MEMORY STATES --
when mem_read1 => -- complete operation from cpu
tomemory <= '1';
if mem_ready = '0' then
nextstate <= mem_read1;
else
nextstate <= mem_read2;
end if;
when mem_read2 => -- switch from cpu to debugger control
mem_switch <= '1';
nextstate <= mem_read3;
when mem_read3 => -- start operation
mem_switch <= '1';
mem_access_dbg <= "010";
if mem_ready = '1' then
nextstate <= mem_read3;
else
nextstate <= mem_read4;
end if;
when mem_read4 => -- finish operation
mem_switch <= '1';
mem_access_dbg <= "010";
load_mem_data <= '1';
if mem_ready = '1' then
nextstate <= mem_restore1;
else
nextstate <= mem_read4;
end if;
-- WRITE MEMORY STATES --
when mem_write1 => -- complete operation from cpu
tomemory <= '1';
if mem_ready = '0' then
nextstate <= mem_write1;
else
nextstate <= mem_write2;
end if;
when mem_write2 => -- switch from cpu to debugger control
mem_switch <= '1';
nextstate <= mem_write3;
when mem_write3 => -- start operation
mem_switch <= '1';
mem_access_dbg <= "100";
if mem_ready = '0' then
nextstate <= mem_write4;
else
nextstate <= mem_write3;
end if;
when mem_write4 => -- finish operation
mem_switch <= '1';
mem_access_dbg <= "100";
if mem_ready = '1' then
nextstate <= mem_restore1;
else
nextstate <= mem_write4;
end if;
-- RESTORE PREVIOUS MEMORY STATES --
when mem_restore1 => -- switch from debugger to cpu control
mem_switch <= '1';
nextstate <= mem_restore2;
when mem_restore2 =>
nextstate <= mem_restore3;
when mem_restore3 => -- wait for completition
if mem_ready = '0' then
nextstate <= mem_restore3;
else
nextstate <= mem_restore4;
end if;
 
when mem_restore4 => -- send back answer via rs232
todebug <= '1';
if data_rx = "00110010" then
nextstate <= busy32; -- read (send 32 bit data back)
else
nextstate <= echo; -- write (send ok back)
end if;
-- FETCH ADDRESS VALUE --
when fetch_address =>
inc <= '1';
ar_shift <= '1';
if counter = "11" then
nextstate <= to_normal;
else
nextstate <= echo;
end if;
-- FETCH DATA VALUE --
when fetch_data =>
inc <= '1';
dr_shift <= '1';
if counter = "11" then
nextstate <= to_normal;
else
nextstate <= echo;
end if;
-- SWITCH TO FETCH ADDRESS MODE --
when to_fetch_address =>
st_input <= "01";
st_set <= '1';
nextstate <= echo;
-- SWITCH TO FETCH DATA MODE --
when to_fetch_data =>
st_input <= "10";
st_set <= '1';
nextstate <= echo;
-- SWITCH TO NORMAL ADDRESS MODE --
when to_normal =>
st_input <= "00";
st_set <= '1';
nextstate <= echo;
-- SWITCH OT FREE RUNNING MODE --
when go =>
tofree <= '1';
nextstate <= echo;
-- END FREE RUNNING MODE --
when pause =>
todebug <= '1';
nextstate <= echo;
-- GENERATE ONE CLOCKTICK --
when clock =>
clocktick <= '1';
nextstate <= echo;
-- RESET CPU --
when reset1 =>
reset_out <= '1';
clocktick <= '1';
nextstate <= reset2;
when reset2 =>
reset_out <= '1';
nextstate <= echo;
-- SEND FLAGS --
when flags =>
in_buffer(7 downto 0) <= ir_ready & mem_ready & mem_access & halted & zero & carry;
load <= '1';
nextstate <= busy8;
-- SEND AKKUMULATOR --
when rega =>
in_buffer(31 downto 0) <= a;
load <= '1';
nextstate <= busy32;
-- SEND REGISTER X --
when regx =>
in_buffer(31 downto 0) <= x;
load <= '1';
nextstate <= busy32;
-- SEND REGISTER > --
when regy =>
in_buffer(31 downto 0) <= y;
load <= '1';
nextstate <= busy32;
-- SEND INSTRUCTION REGISTER --
when regir =>
in_buffer(31 downto 0) <= ir;
load <= '1';
nextstate <= busy32;
-- SEND INSTRUCTION COUNTER --
when regic =>
in_buffer(31 downto 0) <= ic;
load <= '1';
nextstate <= busy32;
-- SEND MEMORY ADDRESS --
when ma =>
in_buffer(31 downto 0) <= mem_addr;
load <= '1';
nextstate <= busy32;
-- SEND MEMORY DATA --
when md =>
in_buffer(31 downto 0) <= mem_data;
load <= '1';
nextstate <= busy32;
-- SEND RECEIVED COMMAND BACK --
when echo =>
in_buffer(7 downto 0) <= data_rx;
load <= '1';
nextstate <= busy8;
 
-- COMMON SENDING ROUTINES --
when busy8 =>
if tx_busy = '0' then
nextstate <= init8;
else
nextstate <= busy8;
end if;
when init8 =>
data_tx <= out_buffer(7 downto 0);
send_data <= '1';
if tx_busy = '1' then
nextstate <= sending8;
else
nextstate <= init8;
end if;
when sending8 =>
if tx_busy = '0' then
nextstate <= waiting;
else
nextstate <= sending8;
end if;
when busy32 =>
if tx_busy = '0' then
nextstate <= init32;
else
nextstate <= busy32;
end if;
when init32 =>
case counter is
when "00" =>
data_tx <= out_buffer(7 downto 0);
when "01" =>
data_tx <= out_buffer(15 downto 8);
when "10" =>
data_tx <= out_buffer(23 downto 16);
when "11" =>
data_tx <= out_buffer(31 downto 24);
when others =>
data_tx <= (others => '0');
end case;
send_data <= '1';
if tx_busy = '1' then
nextstate <= sending32;
else
nextstate <= init32;
end if;
when sending32 =>
if tx_busy = '0' then
nextstate <= inc32;
else
nextstate <= sending32;
end if;
when inc32 =>
inc <= '1';
if counter = "11" then
nextstate <= send_checksum;
else
nextstate <= busy32;
end if;
-- send checksum for 32 bit data
when send_checksum =>
data_tx <= checksum;
send_data <= '1';
if tx_busy = '1' then
nextstate <= sending8;
else
nextstate <= send_checksum;
end if;
end case;
end process;
end rtl;
/branches/avendor/cpu/units/memoryinterface.vhd
0,0 → 1,220
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: memoryinterface
--
-- PURPOSE: memory interface
-- for sram
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
-- WE, OE, SELECT
-- high-active, high-active, 0..scalar 1..vector
 
entity memoryinterface is
port (
clk: in std_logic;
address: in std_logic_vector(31 downto 0) := (others => '0');
access_type: in std_logic_vector(2 downto 0) := "000"; -- we, oe, cs
data_in: in std_logic_vector(31 downto 0);
vdata_in: in vectordata_type;
data_out: out std_logic_vector(31 downto 0);
vdata_out: out vectordata_type;
ready: out std_logic;
we: out std_logic;
en: out std_logic;
addr: out std_logic_vector(31 downto 0);
di: out std_logic_vector(31 downto 0);
do: in std_logic_vector(31 downto 0)
);
end memoryinterface;
 
architecture rtl of memoryinterface is
signal vload : std_logic;
signal vdata_buffer : vectordata_type := (others => (others => '0'));
signal inc: std_logic;
signal res: std_logic;
signal index: integer range 0 to k-1;
signal counter : std_logic_vector(31 downto 0) := (others => '0');
type statetype is (waiting, rw, vr1, vr2, vw1, vw2, vdone1, vdone2);
signal state : statetype := waiting;
signal nextstate : statetype := waiting;
begin
-- derive index from counter
index <= conv_integer(counter) when (counter < k) else 0;
-- counter
process
begin
wait until clk='1' and clk'event;
counter <= counter;
if res = '1' then
counter <= (others => '0');
else
if inc = '1' then
counter <= counter + '1';
end if;
end if;
end process;
-- vregister
process
begin
wait until clk='1' and clk'event;
if vload = '1' then
vdata_buffer(index) <= do;
else
vdata_buffer(index) <= vdata_buffer(index);
end if;
end process;
-- state register
process
begin
wait until clk='1' and clk'event;
state <= nextstate;
end process;
-- state transition
process (clk, address, access_type, data_in, vdata_in, state, do, index, counter)
begin
ready <= '0';
nextstate <= waiting;
res <= '0';
inc <= '0';
vload <= '0';
we <= '0';
en <= '0';
addr <= (others => '0');
di <= (others => '0');
case state is
-- WAITING STATE
when waiting =>
ready <= '1';
case access_type is
when "010" => -- scalar read
ready <= '0';
en <= '1';
addr <= address;
nextstate <= rw;
when "100" => -- scalar write
ready <= '0';
en <= '1';
addr <= address;
we <= '1';
di <= data_in;
nextstate <= rw;
when "011" => -- vector read
ready <= '0';
nextstate <= vr1;
when "101" => -- scalar write
ready <= '0';
nextstate <= vw1;
when others =>
nextstate <= waiting;
end case;
-- READ/WRITE DONE STATE
when rw =>
en <= '1';
addr <= address;
ready <= '1';
if access_type = "000" then
nextstate <= waiting;
else
nextstate <= rw;
end if;
-- VECTOR READ STATES
when vr1 =>
en <= '1';
addr <= address + counter;
nextstate <= vr2;
when vr2 =>
en <= '1';
addr <= address + counter;
inc <= '1';
vload <= '1';
if counter = k-1 then
nextstate <= vdone1;
else
nextstate <= vr1;
end if;
-- VECTOR WRITE STATES
when vw1 =>
en <= '1';
we <= '1';
addr <= address + counter;
di <= vdata_in(index);
nextstate <= vw2;
when vw2 =>
en <= '1';
addr <= address + counter;
vload <= '1';
inc <= '1';
if counter = k-1 then
nextstate <= vdone1;
else
nextstate <= vw1;
end if;
-- VECTOR DONE STATE
when vdone1 =>
res <= '1';
nextstate <= vdone2;
when vdone2 =>
ready <= '1';
if access_type = "000" then
nextstate <= waiting;
else
nextstate <= vdone2;
end if;
end case;
end process;
-- connect outputs
data_out <= do;
vdata_out <= vdata_buffer;
end;
 
/branches/avendor/cpu/units/shuffle.vhd
0,0 → 1,243
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: shuffle
--
-- PURPOSE: shuffle vector registers
-- also required for vmov commands
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity shuffle is
port (
clk: in std_logic;
shuffle_go: in std_logic;
shuffle_valid: out std_logic;
data_in_v: in vectordata_type;
data_in_w: in vectordata_type;
vn: in std_logic_vector(7 downto 0);
ssss: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
shuffle_out_sel: in std_logic_vector(1 downto 0);
data_out: out vectordata_type
);
end shuffle;
 
architecture rtl of shuffle is
constant unit_width: integer := max_shuffle_width / 4;
signal v, w, shuffle_output, output : std_logic_vector(32 * k -1 downto 0);
signal input, reg: std_logic_vector (max_shuffle_width -1 downto 0);
signal perm00, perm01, perm10, permutation : std_logic_vector (max_shuffle_width -1 downto 0);
signal perm00_rev, perm01_rev, perm10_rev, permutation_rev : std_logic_vector (max_shuffle_width -1 downto 0);
 
 
signal reg_input: std_logic_vector(unit_width -1 downto 0);
 
signal shift: std_logic;
signal source: std_logic;
signal sel: std_logic_vector(1 downto 0);
type statetype is (waiting, shuffle);
signal state : statetype := waiting;
signal nextstate : statetype := waiting;
signal counter: std_logic_vector(1 downto 0) := "00";
signal inc, reset: std_logic;
begin
-- convert input from array to std_logic_vector format
v_gen : for i in 0 to k-1 generate
v((i+1) * 32 -1 downto i * 32) <= data_in_v(i);
end generate v_gen;
-- perform shuffle command
shuffle_gen: if use_shuffle generate
w_gen : for i in 0 to k-1 generate
w((i+1) * 32 -1 downto i * 32) <= data_in_w(i);
end generate w_gen;
-- state register
process
begin
wait until clk ='1' and clk'event;
state <= nextstate;
end process;
-- state transitions
process (state, counter, shuffle_go)
begin
-- avoid latches
inc <= '0';
reset <= '0';
shift <= '0';
shuffle_valid <= '0';
case state is
-- WAITING STATE
when waiting =>
shuffle_valid <= '1';
reset <= '1';
if shuffle_go = '1' then
nextstate <= shuffle;
else
nextstate <= waiting;
end if;
-- SHUFFLE STATE
when shuffle =>
shift <= '1';
inc <= '1';
if counter = "11" then
nextstate <= waiting;
else
nextstate <= shuffle;
end if;
end case;
end process;
-- counter
process
begin
wait until clk ='1' and clk'event;
if reset = '1' then
counter <= (others => '0');
else
if inc = '1' then
counter <= counter + '1';
else
counter <= counter;
end if;
end if;
end process;
-- shift register
process
begin
wait until clk ='1' and clk'event;
if shift = '1' then
reg(max_shuffle_width - unit_width -1 downto 0) <= reg(max_shuffle_width -1 downto unit_width);
reg(max_shuffle_width -1 downto max_shuffle_width - unit_width ) <= reg_input;
else
reg <= reg;
end if;
end process;
-- multiplexer
reg_input <= permutation(1* unit_width -1 downto 0 * unit_width) when (sel = "00") else
permutation(2* unit_width -1 downto 1 * unit_width) when (sel = "01") else
permutation(3* unit_width -1 downto 2 * unit_width) when (sel = "10") else
permutation(4* unit_width- 1 downto 3 * unit_width);
-- sel
sel <= vn(7 downto 6) when (counter = "11") else
vn(5 downto 4) when (counter = "10") else
vn(3 downto 2) when (counter = "01") else
vn(1 downto 0);
--source
source <= ssss(3) when (counter = "11") else
ssss(2) when (counter = "10") else
ssss(1) when (counter = "01") else
ssss(0);
-- input multiplexer
input <= v(max_shuffle_width -1 downto 0) when source = '0' else
w(max_shuffle_width -1 downto 0);
-- permutations
permutation_gen : for i in 0 to 3 generate
perm_gen_10: for j in 0 to 1 generate
perm10((i*2+j+1) * unit_width/2 -1 downto (i*2+j)*unit_width/2)
<= input((j*4+i+1)* unit_width/2 -1 downto (j*4+i)* unit_width/2);
perm10_rev((j*4+i+1)* unit_width/2 -1 downto (j*4+i)* unit_width/2)
<= reg((i*2+j+1) * unit_width/2 -1 downto (i*2+j)*unit_width/2);
end generate;
perm_gen_01: for j in 0 to 3 generate
perm01((i*4+j+1) * unit_width/4 -1 downto (i*4+j)*unit_width/4)
<= input((j*4+i+1)* unit_width/4 -1 downto (j*4+i)* unit_width/4);
perm01_rev((j*4+i+1)* unit_width/4 -1 downto (j*4+i)* unit_width/4)
<= reg((i*4+j+1) * unit_width/4 -1 downto (i*4+j)*unit_width/4);
end generate;
perm_gen_00: for j in 0 to 7 generate
perm00((i*8+j+1) * unit_width/8 -1 downto (i*8+j)*unit_width/8)
<= input((j*4+i+1)* unit_width/8 -1 downto (j*4+i)* unit_width/8);
perm00_rev((j*4+i+1)* unit_width/8 -1 downto (j*4+i)* unit_width/8)
<= reg((i*8+j+1) * unit_width/8 -1 downto (i*8+j)*unit_width/8);
end generate;
end generate;
-- vwidth multiplexer
permutation <= input when (vwidth = "11") else
perm10 when (vwidth = "10") else
perm01 when (vwidth = "01") else
perm00;
permutation_rev <= reg when (vwidth = "11") else
perm10_rev when (vwidth = "10") else
perm01_rev when (vwidth = "01") else
perm00_rev;
-- output multiplexer
shuffle_output(max_shuffle_width -1 downto 0) <= permutation_rev(max_shuffle_width -1 downto 0);
greater_gen: if (k*32 > max_shuffle_width) generate
shuffle_output(k*32-1 downto max_shuffle_width) <= v(k*32-1 downto max_shuffle_width);
end generate greater_gen;
end generate;
-- move
not_shuffle_not_shift_gen: if ((not use_shuffle) and (not use_vectorshift)) generate
output <= v;
end generate;
-- move and shuffle
shuffle_not_shift_gen: if ((use_shuffle) and (not use_vectorshift)) generate
output <= shuffle_output when shuffle_out_sel(0) = '0' else v;
end generate;
-- move and vectorshift
not_shuffle_shift_gen: if ((not use_shuffle) and (use_vectorshift)) generate
output <= v(vectorshift_width -1 downto 0) & v(32*k-1 downto vectorshift_width) when shuffle_out_sel = "10" else
v(32*k-vectorshift_width-1 downto 0) & v(32*k-1 downto 32*k-vectorshift_width) when shuffle_out_sel = "11" else
v;
end generate;
-- move, shuffle and vectorshift
shuffle_shift_gen: if ((use_shuffle) and (use_vectorshift)) generate
output <= shuffle_output when shuffle_out_sel = "00" else
v when shuffle_out_sel = "01" else
v(vectorshift_width -1 downto 0) & v(32*k-1 downto vectorshift_width) when shuffle_out_sel = "10" else
v(32*k-vectorshift_width-1 downto 0) & v(32*k-1 downto 32*k-vectorshift_width);
end generate;
-- convert output from std_logic_vector in array format
out_gen : for i in 0 to k-1 generate
data_out(i) <= output((i+1)* 32 -1 downto i * 32);
end generate out_gen;
end rtl;
/branches/avendor/cpu/units/multiplexer2.vhd
0,0 → 1,35
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: multiplexer2
--
-- PURPOSE: multiplexer, two inputs
-- one output
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity multiplexer2 is
generic (
w : positive -- word width
);
port (
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end multiplexer2;
 
architecture rtl of multiplexer2 is
begin
data_out <= data_in_0 when selector = '0' else
data_in_1;
end rtl;
 
/branches/avendor/cpu/units/multiplexer4.vhd
0,0 → 1,39
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: multiplexer4
--
-- PURPOSE: multiplexer, four inputs
-- one output
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.numeric_std.all;
 
entity multiplexer4 is
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end multiplexer4;
 
architecture rtl of multiplexer4 is
begin
data_out <= data_in_00 when selector = "00" else
data_in_01 when selector = "01" else
data_in_10 when selector = "10" else
data_in_11;
end rtl;
 
/branches/avendor/cpu/constraints.ucf
0,0 → 1,8
NET "clk" PERIOD = 20.0ns HIGH 40%;
NET "clk" LOC = "E12"| IOSTANDARD = LVCMOS33;
 
NET "rs232_rxd" LOC = "E16" | IOSTANDARD = LVTTL ;
NET "rs232_txd" LOC = "F15" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW ;
 
NET "reset" LOC = "U15" | IOSTANDARD = LVTTL | PULLDOWN ;
 
/branches/avendor/cpu/system.vhd
0,0 → 1,199
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: system
--
-- PURPOSE: top level module of processor
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all;
use work.datatypes.all;
 
entity system is
port(
clk: in std_logic;
reset: in std_logic;
rs232_txd: out std_logic;
rs232_rxd: in std_logic
);
end system;
 
architecture rtl of system is
component cpu
port(
clk: in std_logic;
reset: in std_logic;
dbg_a: out std_logic_vector(31 downto 0);
dbg_x: out std_logic_vector(31 downto 0);
dbg_y: out std_logic_vector(31 downto 0);
dbg_ir: out std_logic_vector(31 downto 0);
dbg_ic: out std_logic_vector(31 downto 0);
dbg_carry: out std_logic;
dbg_zero: out std_logic;
dbg_ir_ready: out std_logic;
dbg_halted: out std_logic;
mem_data_in: in std_logic_vector(31 downto 0);
mem_data_out: out std_logic_vector(31 downto 0);
mem_vdata_in: in vectordata_type;
mem_vdata_out: out vectordata_type;
mem_address: out std_logic_vector(31 downto 0);
mem_access: out std_logic_vector(2 downto 0);
mem_ready: in std_logic
);
end component;
component memoryinterface
port (
clk: in std_logic;
address: in std_logic_vector(31 downto 0) := (others => '0');
access_type: in std_logic_vector(2 downto 0) := "000"; -- we, oe, cs
data_in: in std_logic_vector(31 downto 0);
vdata_in: in vectordata_type;
data_out: out std_logic_vector(31 downto 0);
vdata_out: out vectordata_type;
ready: out std_logic;
we: out std_logic;
en: out std_logic;
addr: out std_logic_vector(31 downto 0);
di: out std_logic_vector(31 downto 0);
do: in std_logic_vector(31 downto 0)
);
end component;
component debugger
port (
clk_in: in std_logic;
clk_cpu: out std_logic;
clk_mem: out std_logic;
reset_out: out std_logic;
rs232_txd: out std_logic;
rs232_rxd: in std_logic;
a: in std_logic_vector(31 downto 0);
x: in std_logic_vector(31 downto 0);
y: in std_logic_vector(31 downto 0);
ir: in std_logic_vector(31 downto 0);
ic: in std_logic_vector(31 downto 0);
mem_switch: out std_logic;
mem_ready: in std_logic;
mem_access: in std_logic_vector(2 downto 0);
mem_access_dbg: out std_logic_vector(2 downto 0);
mem_addr: in std_logic_vector(31 downto 0);
mem_addr_dbg: out std_logic_vector(31 downto 0);
mem_data: in std_logic_vector(31 downto 0);
mem_data_dbg: out std_logic_vector(31 downto 0);
carry: in std_logic;
zero: in std_logic;
ir_ready: in std_logic;
halted: in std_logic
);
end component;
component sram
port (
clk : in std_logic;
we : in std_logic;
en : in std_logic;
addr : in std_logic_vector(31 downto 0);
di : in std_logic_vector(31 downto 0);
do : out std_logic_vector(31 downto 0)
);
end component;
for sram_impl: sram use entity work.sram(rtl);
for cpu_impl: cpu use entity work.cpu(rtl);
for memoryinterface_impl: memoryinterface use entity work.memoryinterface(rtl);
for debugger_impl: debugger use entity work.debugger(rtl);
-- sram signals
signal we, en: std_logic;
signal addr, di, do: std_logic_vector(31 downto 0);
-- debugger signals
signal clk_cpu: std_logic;
signal clk_mem: std_logic;
signal reset_cpu: std_logic;
signal mem_switch: std_logic;
-- cpu signals
signal dbg_a, dbg_x, dbg_y, dbg_ir, dbg_ic: std_logic_vector(31 downto 0);
signal dbg_carry, dbg_zero, dbg_ir_ready, dbg_halted: std_logic;
-- memory interface signals
signal mem_access, mem_access_cpu, mem_access_dbg: std_logic_vector(2 downto 0);
signal mem_address, mem_address_cpu, mem_address_dbg: std_logic_vector(31 downto 0);
signal mem_data_out, mem_data_out_cpu, mem_data_out_dbg: std_logic_vector(31 downto 0);
signal mem_data_in: std_logic_vector(31 downto 0);
signal mem_vdata_in, mem_vdata_out: vectordata_type;
signal mem_ready: std_logic;
-- attributes for xilinx synthesis tool
attribute clock_signal : string;
attribute clock_signal of "clk" : signal is "yes";
attribute clock_signal of "clk_cpu" : signal is "yes";
 
begin
-- include debugger
debugger_gen: if use_debugger generate
debugger_impl: debugger
port map (
clk_in => clk, clk_cpu => clk_cpu, clk_mem => clk_mem, reset_out => reset_cpu,
rs232_txd => rs232_txd, rs232_rxd => rs232_rxd, a => dbg_a, x => dbg_x, y => dbg_y, ir =>
dbg_ir, ic => dbg_ic, mem_switch => mem_switch, mem_ready => mem_ready, mem_access =>
mem_access_cpu, mem_access_dbg => mem_access_dbg, mem_addr => mem_address_cpu,
mem_addr_dbg => mem_address_dbg, mem_data => mem_data_in, mem_data_dbg => mem_data_out_dbg,
carry => dbg_carry, zero => dbg_zero, ir_ready => dbg_ir_ready, halted => dbg_halted
);
-- allow memory access from debugger unit
mem_access <= mem_access_cpu when mem_switch = '0' else mem_access_dbg;
mem_address <= mem_address_cpu when mem_switch = '0' else mem_address_dbg;
mem_data_out <= mem_data_out_cpu when mem_switch = '0' else mem_data_out_dbg;
end generate;
-- dont include debugger
not_debugger_gen: if not use_debugger generate
reset_cpu <= reset;
clk_cpu <= clk;
-- allow memory access only from cpu
mem_access <= mem_access_cpu;
mem_address <= mem_address_cpu;
mem_data_out <= mem_data_out_cpu;
end generate;
cpu_impl: cpu
port map (
clk => clk_cpu, reset => reset_cpu, dbg_a => dbg_a, dbg_x => dbg_x, dbg_y => dbg_y,
dbg_ir => dbg_ir, dbg_ic => dbg_ic, dbg_carry => dbg_carry, dbg_zero => dbg_zero,
dbg_ir_ready => dbg_ir_ready, dbg_halted => dbg_halted, mem_data_in => mem_data_in,
mem_data_out => mem_data_out_cpu, mem_vdata_in => mem_vdata_in, mem_vdata_out => mem_vdata_out,
mem_address => mem_address_cpu, mem_access => mem_access_cpu, mem_ready => mem_ready
);
memoryinterface_impl: memoryinterface
port map (
clk => clk_mem, address => mem_address, access_type => mem_access, data_in => mem_data_out,
vdata_in => mem_vdata_out, data_out => mem_data_in, vdata_out => mem_vdata_in, ready => mem_ready,
we => we, en => en, addr => addr, di => di, do => do
);
sram_impl: sram
port map (
clk => clk_mem, we => we, en => en, addr => addr, di => di, do => do
);
end;
 
/branches/avendor/cpu/config.vhd
0,0 → 1,33
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: cfg
--
-- PURPOSE: base configuration file
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
package cfg is
-- configuration
constant n: integer := 10; -- amount of vector registers
constant k: integer := 20; -- amount words per vector register (even numbers)
constant use_debugger: boolean := true; -- include debugging unit
constant use_scalar_mult : boolean := true; -- allow multiplications in scalar alu
constant use_vector_mult : boolean := false; -- allow multiplications in vector alu
constant use_shuffle : boolean := false; -- use shuffle unit
constant max_shuffle_width : integer := 0; -- max. shuffle width (dividable by 4)
constant use_vectorshift : boolean := true; -- allow shift of vector registers (vmol, vmor)
constant vectorshift_width : integer := 32; -- width of vectorshift in bit
 
constant sram_size : integer := 4096; -- sram size (memory size: 32 bit * sram_size)
end cfg;
/branches/avendor/cpu/testbenches/tb_multiplexer2.vhd
0,0 → 1,73
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_multiplexer2
--
-- PURPOSE: testbench of multiplexer2 entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_multiplexer2 is
end tb_multiplexer2;
 
architecture testbench of tb_multiplexer2 is
component multiplexer2
generic (
w : positive
);
port(
selector: in std_logic;
data_in_0: in std_logic_vector(w-1 downto 0);
data_in_1: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
for impl: multiplexer2 use entity work.multiplexer2(rtl);
signal selector: std_logic := '0';
signal data_in_0: std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal data_in_1: std_logic_vector(31 downto 0) := "00000000000000000000000000000001";
 
signal data_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: multiplexer2
generic map (w => 32)
port map (selector => selector, data_in_0 => data_in_0, data_in_1 => data_in_1,
data_out => data_out);
process
begin
wait for 100ns;
-- selector = 0
selector <= '0';
wait for period;
assert data_out = "00000000000000000000000000000000"
report "selector=0 : data_out"
severity Error;
-- selector = 1
selector <= '1';
wait for period;
assert data_out = "00000000000000000000000000000001"
report "selector=1 : data_out"
severity Error;
 
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_aluinputgroup.vhd
0,0 → 1,228
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_aluinputgrp
--
-- PURPOSE: testbench of aluinputgroup entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_aluinputgroup is
end tb_aluinputgroup;
 
architecture testbench of tb_aluinputgroup is
component aluinputgroup
port(
clk: in std_logic;
memory_in: in std_logic_vector(31 downto 0);
x_in: in std_logic_vector(31 downto 0);
y_in: in std_logic_vector(31 downto 0);
a_in: in std_logic_vector(31 downto 0);
ir_out: out std_logic_vector(31 downto 0);
k_out: out std_logic_vector(31 downto 0);
vector_out: out std_logic_vector(31 downto 0);
a_out: out std_logic_vector(31 downto 0);
b_out: out std_logic_vector(31 downto 0);
sel_a: in std_logic_vector(1 downto 0);
sel_b: in std_logic_vector(1 downto 0);
sel_source_a: in std_logic;
sel_source_b: in std_logic;
load_ir: in std_logic
);
end component;
for impl: aluinputgroup use entity work.aluinputgroup(rtl);
signal clk: std_logic;
signal memory_in: std_logic_vector(31 downto 0); -- data from ram
signal x_in: std_logic_vector(31 downto 0);
signal y_in: std_logic_vector(31 downto 0);
signal a_in: std_logic_vector(31 downto 0);
signal ir_out: std_logic_vector(31 downto 0);
signal k_out: std_logic_vector(31 downto 0); -- k for vector unit
signal vector_out: std_logic_vector(31 downto 0); -- data for vector unit
signal a_out: std_logic_vector(31 downto 0);
signal b_out: std_logic_vector(31 downto 0);
signal sel_a: std_logic_vector(1 downto 0);
signal sel_b: std_logic_vector(1 downto 0);
signal sel_source_a: std_logic; -- c8
signal sel_source_b: std_logic; -- c0
signal load_ir: std_logic;
 
constant period : time := 2ns;
begin
impl: aluinputgroup port map (clk => clk, memory_in => memory_in, x_in => x_in, y_in => y_in,
a_in => a_in, ir_out => ir_out, k_out => k_out, vector_out => vector_out, a_out => a_out,
b_out => b_out, sel_a => sel_a, sel_b => sel_b, sel_source_a => sel_source_a, sel_source_b
=> sel_source_b, load_ir => load_ir);
process
begin
wait for 100ns;
-- 1: load ir, a_out register a, b_out memory, vector_out register a, k_out register x
memory_in <= "11010011110100111101001111010011";
a_in <= "01001100010011000100110001001100";
x_in <= "11001010110010101100101011001010";
load_ir <= '1';
sel_source_a <= '0';
sel_source_b <= '1';
sel_a <= "01";
sel_b <= "10";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ir_out = "11010011110100111101001111010011"
report "1 : ir_out"
severity Error;
assert a_out = "01001100010011000100110001001100"
report "1 : a_out"
severity Error;
assert b_out = "11010011110100111101001111010011"
report "1 : b_out"
severity Error;
assert k_out = "11001010110010101100101011001010"
report "1 : k_out"
severity Error;
assert vector_out = "01001100010011000100110001001100"
report "1 : vector_out"
severity Error;
-- 2: not load ir, a_out register y, b_out n, vector_out y, k_out n
y_in <= "10011001100110011001100110011001";
load_ir <= '0';
sel_source_a <= '0';
sel_source_b <= '0';
sel_a <= "11";
sel_b <= "00";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ir_out = "11010011110100111101001111010011"
report "2 : ir_out"
severity Error;
assert a_out = "10011001100110011001100110011001"
report "2 : a_out"
severity Error;
assert b_out = "00000000000000001101001111010011"
report "2 : b_out"
severity Error;
assert k_out = "00000000000000001101001111010011"
report "2 : k_out"
severity Error;
assert vector_out = "10011001100110011001100110011001"
report "2 : vector_out"
severity Error;
-- 3: not load ir, a_out 0, b_out a, vector_out 0, k_out register a
load_ir <= '0';
sel_source_a <= '0';
sel_source_b <= '0';
sel_a <= "00";
sel_b <= "01";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ir_out = "11010011110100111101001111010011"
report "3 : ir_out"
severity Error;
assert a_out = "00000000000000000000000000000000"
report "3 : a_out"
severity Error;
assert b_out = "01001100010011000100110001001100"
report "3 : b_out"
severity Error;
assert k_out = "01001100010011000100110001001100"
report "3 : k_out"
severity Error;
assert vector_out = "00000000000000000000000000000000"
report "3 : vector_out"
severity Error;
-- 4: load ir, a_out register x, b_out select y, vector_out register x, k_out register y
memory_in <= "01101101011011010110110101101101";
load_ir <= '1';
sel_source_a <= '0';
sel_source_b <= '0';
sel_a <= "10";
sel_b <= "11";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ir_out = "01101101011011010110110101101101"
report "4 : ir_out"
severity Error;
assert a_out = "11001010110010101100101011001010"
report "4 : a_out"
severity Error;
assert b_out = "10011001100110011001100110011001"
report "4 : b_out"
severity Error;
assert k_out = "10011001100110011001100110011001"
report "4 : k_out"
severity Error;
assert vector_out = "11001010110010101100101011001010"
report "4 : vector_out"
severity Error;
-- 5: load ir, a_out select 0, b_out register y, vector_out register x, k_out y
memory_in <= "01101101011011010110110101101101";
load_ir <= '1';
sel_source_a <= '1';
sel_source_b <= '0';
sel_a <= "10";
sel_b <= "11";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ir_out = "01101101011011010110110101101101"
report "5 : ir_out"
severity Error;
assert a_out = "00000000000000000000000000000000"
report "5 : a_out"
severity Error;
assert b_out = "10011001100110011001100110011001"
report "5 : b_out"
severity Error;
assert k_out = "10011001100110011001100110011001"
report "5 : k_out"
severity Error;
assert vector_out = "11001010110010101100101011001010"
report "5 : vector_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_dataregister.vhd
0,0 → 1,91
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_dataregister
--
-- PURPOSE: testbench of dataregister entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_dataregister is
end tb_dataregister;
 
architecture testbench of tb_dataregister is
component dataregister
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
for impl: dataregister use entity work.dataregister(rtl);
signal clk: std_logic;
signal load: std_logic;
signal data_in: std_logic_vector(31 downto 0);
signal data_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: dataregister port map (clk => clk, load => load, data_in => data_in,
data_out => data_out);
process
begin
wait for 100ns;
-- load 1
data_in <= "11101110111011101110111011101110";
load <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11101110111011101110111011101110"
report "load 1 : data_out"
severity Error;
-- load = 'Z'
data_in <= "00000000000000000000000000000001";
load <= 'Z';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11101110111011101110111011101110"
report "load=z : data_out"
severity Error;
-- not load
data_in <= "11111111111111111111111111111111";
load <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11101110111011101110111011101110"
report "not load: data_out"
severity Error;
-- load 2
data_in <= "10101010101010101010101010101010";
load <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "10101010101010101010101010101010"
report "load 2 : data_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_multiplexer4.vhd
0,0 → 1,94
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_multiplexer4
--
-- PURPOSE: testbench of multiplexer4 entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_multiplexer4 is
end tb_multiplexer4;
 
architecture testbench of tb_multiplexer4 is
component multiplexer4
generic (
w : positive
);
port (
selector: in std_logic_vector(1 downto 0);
data_in_00: in std_logic_vector(w-1 downto 0);
data_in_01: in std_logic_vector(w-1 downto 0);
data_in_10: in std_logic_vector(w-1 downto 0);
data_in_11: in std_logic_vector(w-1 downto 0);
data_out: out std_logic_vector(w-1 downto 0)
);
end component;
for impl: multiplexer4 use entity work.multiplexer4(rtl);
signal selector: std_logic_vector(1 downto 0) := "00";
signal data_in_00: std_logic_vector(31 downto 0) := "10101100101011001010110010101100";
signal data_in_01: std_logic_vector(31 downto 0) := "11001001110010011100100111001001";
signal data_in_10: std_logic_vector(31 downto 0) := "01100110011001100110011001100110";
signal data_in_11: std_logic_vector(31 downto 0) := "11001111110011111100111111001111";
signal data_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: multiplexer4
generic map (w => 32)
port map (selector => selector, data_in_00 => data_in_00, data_in_01 => data_in_01,
data_in_10 => data_in_10, data_in_11 => data_in_11, data_out => data_out);
process
begin
wait for 100ns;
-- selector = 00
selector <= "00";
wait for period;
assert data_out = "10101100101011001010110010101100"
report "selector=00 : data_out"
severity Error;
-- selector = 01
selector <= "01";
wait for period;
assert data_out = "11001001110010011100100111001001"
report "selector=01 : data_out"
severity Error;
-- selector = 10
selector <= "10";
wait for period;
assert data_out = "01100110011001100110011001100110"
report "selector=10 : data_out"
severity Error;
-- selector = 11
selector <= "11";
wait for period;
assert data_out = "11001111110011111100111111001111"
report "selector=11 : data_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_selectunit.vhd
0,0 → 1,144
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_selectunit
--
-- PURPOSE: testbench of selectunit entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
use work.cfg.all; -- testbench requires k > 7
use work.datatypes.all;
 
entity tb_selectunit is
end tb_selectunit;
 
 
 
architecture testbench of tb_selectunit is
component selectunit
port (
data_in : in vectordata_type;
k_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
for impl: selectunit use entity work.selectunit(rtl);
signal data_in: vectordata_type;
signal k_in: std_logic_vector(31 downto 0) := (others => '0');
signal data_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: selectunit port map (data_in => data_in, k_in => k_in, data_out => data_out);
process
begin
wait for 100ns;
assert k > 7
report "testbench requires k > 7"
severity Error;
data_in(0) <= "10101100110111001001111000101111";
data_in(1) <= "01001011011011101010101101010100";
data_in(2) <= "11101101110110101011011011101010";
data_in(3) <= "11001100110011001100110011001101";
data_in(4) <= "11001011001001100101110010011000";
data_in(5) <= "10010010100100101001001010010010";
data_in(6) <= "11111000000111111100000011111000";
data_in(7) <= "10101010101010101010101010101010";
-- k = 0
k_in <= "00000000000000000000000000000000";
wait for period;
assert data_out = "10101100110111001001111000101111"
report "k=0 : data_out"
severity Error;
-- k = 1
k_in <= "00000000000000000000000000000001";
wait for period;
assert data_out = "01001011011011101010101101010100"
report "k=1 : data_out"
severity Error;
-- k = 2
k_in <= "00000000000000000000000000000010";
wait for period;
assert data_out = "11101101110110101011011011101010"
report "k=2 : data_out"
severity Error;
-- k = 3
k_in <= "00000000000000000000000000000011";
wait for period;
assert data_out = "11001100110011001100110011001101"
report "k=3 : data_out"
severity Error;
-- k = 4
k_in <= "00000000000000000000000000000100";
wait for period;
assert data_out = "11001011001001100101110010011000"
report "k=4 : data_out"
severity Error;
-- k = 5
k_in <= "00000000000000000000000000000101";
wait for period;
assert data_out = "10010010100100101001001010010010"
report "k=5 : data_out"
severity Error;
-- k = 6
k_in <= "00000000000000000000000000000110";
wait for period;
assert data_out = "11111000000111111100000011111000"
report "k=6 : data_out"
severity Error;
-- k = 7
k_in <= "00000000000000000000000000000111";
wait for period;
assert data_out = "10101010101010101010101010101010"
report "k=100000 : data_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_demultiplexer1x4.vhd
0,0 → 1,139
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_demultiplexer
--
-- PURPOSE: testbench of demultiplexer entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_demultiplexer1x4 is
end tb_demultiplexer1x4;
 
architecture testbench of tb_demultiplexer1x4 is
component demultiplexer1x4
port( selector: in std_logic_vector(1 downto 0);
data_in: in std_logic;
data_out_00: out std_logic;
data_out_01: out std_logic;
data_out_10: out std_logic;
data_out_11: out std_logic
);
end component;
for impl: demultiplexer1x4 use entity work.demultiplexer1x4(rtl);
signal selector: std_logic_vector(1 downto 0) := "00";
signal data_in: std_logic := '1';
signal data_out_00: std_logic;
signal data_out_01: std_logic;
signal data_out_10: std_logic;
signal data_out_11: std_logic;
constant period : time := 2ns;
begin
impl: demultiplexer1x4 port map (selector => selector, data_in => data_in, data_out_00 => data_out_00,
data_out_01 => data_out_01, data_out_10 => data_out_10, data_out_11 => data_out_11);
process
begin
wait for 100ns;
-- selector = 00
selector <= "00";
wait for period;
assert data_out_00 = '1'
report "selector=00 : data_out_00"
severity Error;
assert data_out_01 = '0'
report "selector=00 : data_out_01"
severity Error;
assert data_out_10 = '0'
report "selector=00 : data_out_10"
severity Error;
assert data_out_11 = '0'
report "selector=00 : data_out_11"
severity Error;
-- selector = 01
selector <= "01";
wait for period;
assert data_out_00 = '0'
report "selector=01 : data_out_00"
severity Error;
assert data_out_01 = '1'
report "selector=01 : data_out_01"
severity Error;
assert data_out_10 = '0'
report "selector=01 : data_out_10"
severity Error;
assert data_out_11 = '0'
report "selector=01 : data_out_11"
severity Error;
-- selector = 10
selector <= "10";
wait for period;
assert data_out_00 = '0'
report "selector=10 : data_out_00"
severity Error;
assert data_out_01 = '0'
report "selector=10 : data_out_01"
severity Error;
assert data_out_10 = '1'
report "selector=10 : data_out_10"
severity Error;
assert data_out_11 = '0'
report "selector=10 : data_out_11"
severity Error;
 
-- selector = 11
selector <= "11";
wait for period;
assert data_out_00 = '0'
report "selector=11 : data_out_00"
severity Error;
assert data_out_01 = '0'
report "selector=11 : data_out_01"
severity Error;
assert data_out_10 = '0'
report "selector=11 : data_out_10"
severity Error;
assert data_out_11 = '1'
report "selector=11 : data_out_11"
severity Error;
 
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_alu.vhd
0,0 → 1,477
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_alu
--
-- PURPOSE: testbench of scalar alu entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_alu is
end tb_alu;
 
architecture testbench of tb_alu is
component alu
port(
a_in: in std_logic_vector(31 downto 0);
b_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
aluop: in std_logic_vector(3 downto 0);
op_select: in std_logic;
zero_out: out std_logic;
carry_out: out std_logic;
alu_out: out std_logic_vector(31 downto 0)
);
end component;
for impl: alu use entity work.alu(rtl);
signal a_in: std_logic_vector(31 downto 0);
signal b_in: std_logic_vector(31 downto 0);
signal carry_in: std_logic;
signal aluop: std_logic_vector(3 downto 0);
signal op_select: std_logic := '0';
signal carry_out: std_logic;
signal zero_out: std_logic;
signal alu_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: alu
port map (
a_in => a_in, b_in => b_in, carry_in => carry_in, aluop =>
aluop, op_select => op_select, carry_out => carry_out,
zero_out => zero_out, alu_out => alu_out);
process
begin
wait for 100ns;
-- ###############################################################
-- add 1: zero_out clear, carry_out_clear
a_in <= "10010000001000010000000001010101";
b_in <= "01000010000000000001000100000010";
carry_in <= '0';
aluop <= "0000";
wait for period;
assert alu_out = "11010010001000010001000101010111"
report "add 1 : alu_out"
severity Error;
assert carry_out = '0'
report "add 1 : carry_out"
severity Error;
assert zero_out = '0'
report "add 1 : zero_out"
severity Error;
-- add 2: zero_out set, carry_out clear
a_in <= "00000000000000000000000000000000";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "0000";
wait for period;
assert alu_out = "00000000000000000000000000000000"
report "add 2 : alu_out"
severity Error;
assert carry_out = '0'
report "add 2 : carry_out"
severity Error;
assert zero_out = '1'
report "add 2 : zero_out"
severity Error;
-- add 3: zero_out clear, carry_out set
a_in <= "11111111111111111111111111111111";
b_in <= "11111111111111111111111111111111";
carry_in <= '0';
aluop <= "0000";
wait for period;
assert alu_out = "11111111111111111111111111111110"
report "add 3 : alu_out"
severity Error;
assert carry_out = '1'
report "add 3 : carry_out"
severity Error;
assert zero_out = '0'
report "add 3 : zero_out"
severity Error;
-- ###############################################################
-- adc 1: carry_in set, zero_out clear, carry_out_clear
a_in <= "00000000000000000000000000000100";
b_in <= "00000000000000000000000000000010";
carry_in <= '1';
aluop <= "0001";
wait for period;
assert alu_out = "00000000000000000000000000000111"
report "adc 1 : alu_out"
severity Error;
assert carry_out = '0'
report "adc 1 : carry_out"
severity Error;
assert zero_out = '0'
report "adc 1 : zero_out"
severity Error;
-- adc 2: carry_in clear, zero_out clear, carry_out_clear
a_in <= "00000000000000000000000000000100";
b_in <= "00000000000000000000000000000010";
carry_in <= '0';
aluop <= "0001";
wait for period;
assert alu_out = "00000000000000000000000000000110"
report "adc 2 : alu_out"
severity Error;
assert carry_out = '0'
report "adc 2 : carry_out"
severity Error;
assert zero_out = '0'
report "adc 2 : zero_out"
severity Error;
-- ###############################################################
-- sub 1: result positive, zero_out clear, carry_out clear
a_in <= "00000000000000000000000010101011";
b_in <= "00000000000000000000000010100010";
carry_in <= '0';
aluop <= "0010";
wait for period;
assert alu_out = "00000000000000000000000000001001"
report "sub 1 : alu_out"
severity Error;
assert carry_out = '0'
report "sub 1 : carry_out"
severity Error;
assert zero_out = '0'
report "sub 1 : zero_out"
severity Error;
 
-- sub 2: result negative, zero_out clear, carry_out set
a_in <= "00000000000000000000000000000000";
b_in <= "00000000000000000000000000000001";
carry_in <= '0';
aluop <= "0010";
wait for period;
assert alu_out = "11111111111111111111111111111111"
report "sub 2 : alu_out"
severity Error;
assert carry_out = '1'
report "sub 2 : carry_out"
severity Error;
assert zero_out = '0'
report "sub 2 : zero_out"
severity Error;
-- ###############################################################
-- sbc 1: carry_in set, result positive, zero_out clear, carry_out clear
a_in <= "00000000000000000000000010101011";
b_in <= "00000000000000000000000010100010";
carry_in <= '1';
aluop <= "0011";
wait for period;
assert alu_out = "00000000000000000000000000001000"
report "sub 1 : alu_out"
severity Error;
assert carry_out = '0'
report "sub 1 : carry_out"
severity Error;
assert zero_out = '0'
report "sub 1 : zero_out"
severity Error;
 
-- sbc 2: carry_in clear, result positive, zero_out clear, carry_out clear
a_in <= "00000000000000000000000010101011";
b_in <= "00000000000000000000000010100010";
carry_in <= '0';
aluop <= "0011";
wait for period;
assert alu_out = "00000000000000000000000000001001"
report "sub 2 : alu_out"
severity Error;
assert carry_out = '0'
report "sub 2 : carry_out"
severity Error;
assert zero_out = '0'
report "sub2 : zero_out"
severity Error;
 
-- ###############################################################
-- inc:
a_in <= "00000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "0100";
wait for period;
assert alu_out = "00000000000000000000000000000100"
report "inc : alu_out"
severity Error;
assert carry_out = '0'
report "inc : carry_out"
severity Error;
assert zero_out = '0'
report "inc : zero_out"
severity Error;
-- ###############################################################
-- dec:
a_in <= "00000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "0110";
wait for period;
assert alu_out = "00000000000000000000000000000010"
report "dec : alu_out"
severity Error;
assert carry_out = '0'
report "dec : carry_out"
severity Error;
assert zero_out = '0'
report "dec : zero_out"
severity Error;
 
-- ###############################################################
-- and:
a_in <= "11010000000000000000000000001011";
b_in <= "10110000000000000000000000001101";
carry_in <= '0';
aluop <= "1000";
wait for period;
assert alu_out = "10010000000000000000000000001001"
report "and : alu_out"
severity Error;
assert carry_out = '0'
report "and : carry_out"
severity Error;
assert zero_out = '0'
report "and : zero_out"
severity Error;
-- ###############################################################
-- or:
a_in <= "11010000000000000000000000001011";
b_in <= "10110000000000000000000000001101";
carry_in <= '0';
aluop <= "1001";
wait for period;
assert alu_out = "11110000000000000000000000001111"
report "or : alu_out"
severity Error;
assert carry_out = '0'
report "or : carry_out"
severity Error;
assert zero_out = '0'
report "or : zero_out"
severity Error;
-- ###############################################################
-- xor:
a_in <= "11010000000000000000000000001011";
b_in <= "10110000000000000000000000001101";
carry_in <= '0';
aluop <= "1010";
wait for period;
assert alu_out = "01100000000000000000000000000110"
report "xor : alu_out"
severity Error;
assert carry_out = '0'
report "xor : carry_out"
severity Error;
assert zero_out = '0'
report "xor : zero_out"
severity Error;
-- ###############################################################
-- lsl:
a_in <= "11000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "1100";
wait for period;
assert alu_out = "10000000000000000000000000000110"
report "lsl : alu_out"
severity Error;
assert carry_out = '1'
report "lsl : carry_out"
severity Error;
assert zero_out = '0'
report "lsl : zero_out"
severity Error;
-- ###############################################################
-- lsr:
a_in <= "11000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "1110";
wait for period;
assert alu_out = "01100000000000000000000000000001"
report "lsr : alu_out"
severity Error;
assert carry_out = '1'
report "lsr : carry_out"
severity Error;
assert zero_out = '0'
report "lsr : zero_out"
severity Error;
-- ###############################################################
-- rol: carry_in set
a_in <= "11000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '1';
aluop <= "1101";
wait for period;
assert alu_out = "10000000000000000000000000000111"
report "rol : alu_out"
severity Error;
assert carry_out = '1'
report "rol : carry_out"
severity Error;
assert zero_out = '0'
report "rol : zero_out"
severity Error;
-- ###############################################################
-- ror: carry_in set
a_in <= "11000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '1';
aluop <= "1111";
wait for period;
assert alu_out = "11100000000000000000000000000001"
report "ror : alu_out"
severity Error;
assert carry_out = '1'
report "ror : carry_out"
severity Error;
assert zero_out = '0'
report "ror : zero_out"
severity Error;
-- ###############################################################
op_select <= '1';
-- add:
a_in <= "11000000000000000000000000000011";
b_in <= "00000000000000000000000000000000";
carry_in <= '0';
aluop <= "1111";
wait for period;
assert alu_out = "11000000000000000000000000000011"
report "ror : alu_out"
severity Error;
assert carry_out = '0'
report "ror : carry_out"
severity Error;
assert zero_out = '0'
report "ror : zero_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_instructioncounter.vhd
0,0 → 1,150
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_addressgroup
--
-- PURPOSE: testbench of instruction counter entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_instructioncounter is
end tb_instructioncounter;
 
architecture testbench of tb_instructioncounter is
component instructioncounter
port( clk: in std_logic;
load: in std_logic;
inc: in std_logic;
reset: in std_logic;
data_in: in std_logic_vector(31 downto 0);
data_out: out std_logic_vector(31 downto 0)
);
end component;
for impl: instructioncounter use entity work.instructioncounter(rtl);
signal clk: std_logic;
signal load: std_logic;
signal inc: std_logic;
signal reset: std_logic := '0';
signal data_in: std_logic_vector(31 downto 0);
signal data_out: std_logic_vector(31 downto 0);
constant period : time := 2ns;
begin
impl: instructioncounter port map (clk => clk, load => load, inc => inc, reset => reset,
data_in => data_in, data_out => data_out);
process
begin
wait for 100ns;
-- load 1
data_in <= "11001100110011001100110011001100";
load <= '1';
inc <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11001100110011001100110011001100"
report "load 1 : data_out"
severity Error;
-- load = inc = 0
data_in <= "01010101010101010101010101010101";
load <= '0';
inc <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11001100110011001100110011001100"
report "load=inc=0: data_out"
severity Error;
-- load 2
data_in <= "10101010101010101010101010101010";
load <= '1';
inc <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "10101010101010101010101010101010"
report "load 2 : data_out"
severity Error;
-- load = inc = 1
data_in <= "01110001011100010111000101110001";
load <= '1';
inc <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "10101010101010101010101010101010"
report "load=inc=1 : data_out"
severity Error;
-- load 3
data_in <= "11111111111111111111111111111110";
load <= '1';
inc <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11111111111111111111111111111110"
report "load 3 : data_out"
severity Error;
-- inc
data_in <= "10101010101010101010101010101010";
load <= '0';
inc <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "11111111111111111111111111111111"
report "inc : data_out"
severity Error;
-- inc overflow
data_in <= "10101010101010101010101010101010";
load <= '0';
inc <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "00000000000000000000000000000000"
report "inc overflow: data_out"
severity Error;
-- reset
data_in <= "10101010101010101010101010101010";
load <= '1';
inc <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
reset <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = "00000000000000000000000000000000"
report "reset: data_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_registergroup.vhd
0,0 → 1,145
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_registergroup
--
-- PURPOSE: testbench of registergroup entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_registergroup is
end tb_registergroup;
 
architecture testbench of tb_registergroup is
component registergroup
port( clk: in std_logic;
result_in: in std_logic_vector(31 downto 0);
vector_in: in std_logic_vector(31 downto 0);
ic_in: in std_logic_vector(31 downto 0);
enable_in: in std_logic;
x_out: out std_logic_vector(31 downto 0);
y_out: out std_logic_vector(31 downto 0);
a_out: out std_logic_vector(31 downto 0);
sel_source: in std_logic_vector(1 downto 0);
sel_dest: in std_logic_vector(1 downto 0)
);
end component;
for impl: registergroup use entity work.registergroup(rtl);
signal clk: std_logic;
signal result_in: std_logic_vector(31 downto 0);
signal vector_in: std_logic_vector(31 downto 0);
signal ic_in: std_logic_vector(31 downto 0);
signal enable_in: std_logic := '1';
signal x_out: std_logic_vector(31 downto 0);
signal y_out: std_logic_vector(31 downto 0);
signal a_out: std_logic_vector(31 downto 0);
signal sel_source: std_logic_vector(1 downto 0);
signal sel_dest: std_logic_vector(1 downto 0);
constant period : time := 2ns;
begin
impl: registergroup port map (clk => clk, result_in => result_in, vector_in => vector_in,
ic_in => ic_in, enable_in => enable_in, x_out => x_out, y_out => y_out, a_out => a_out,
sel_source => sel_source, sel_dest => sel_dest);
process
begin
wait for 100ns;
-- 1: load a from alu, store
result_in <= "10110011101100111011001110110011";
sel_source <= "00";
sel_dest <= "01";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert a_out = "10110011101100111011001110110011"
report "1 : a_out_out"
severity Error;
-- 2: load x from vector
vector_in <= "11100010111000101110001011100010";
sel_source <= "10";
sel_dest <= "10";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert a_out = "10110011101100111011001110110011"
report "2 : a_out_out"
severity Error;
assert x_out = "11100010111000101110001011100010"
report "2 : x_out"
severity Error;
-- 3: load nothing
sel_source <= "00";
sel_dest <= "00";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert a_out = "10110011101100111011001110110011"
report "3 : a_out_out"
severity Error;
assert x_out = "11100010111000101110001011100010"
report "3 : x_out"
severity Error;
-- 4: load y from ic, store ic
result_in <= "10110011101100111011001110110011";
ic_in <= "10010010110110100111010101101101";
sel_source <= "01";
sel_dest <= "11";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert a_out = "10110011101100111011001110110011"
report "4 : a_out_out"
severity Error;
assert x_out = "11100010111000101110001011100010"
report "4 : x_out"
severity Error;
assert y_out = "10010010110110100111010101101101"
report "4 : y_out"
severity Error;
-- 5: dont load y from alu (enable clear)
result_in <= "11110000111100001111000011110000";
enable_in <= '0';
sel_source <= "00";
sel_dest <= "11";
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert a_out = "10110011101100111011001110110011"
report "5 : a_out_out"
severity Error;
assert x_out = "11100010111000101110001011100010"
report "5 : x_out"
severity Error;
assert y_out = "10010010110110100111010101101101"
report "5 : y_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_addressgroup.vhd
0,0 → 1,120
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_addressgroup
--
-- PURPOSE: testbench of addressgroup entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_addressgroup is
end tb_addressgroup;
 
architecture testbench of tb_addressgroup is
component addressgroup
port( clk: in std_logic;
address_in: in std_logic_vector(31 downto 0);
address_out: out std_logic_vector(31 downto 0);
ic_out: out std_logic_vector(31 downto 0);
sel_source: in std_logic;
inc: in std_logic;
load_ic: in std_logic;
reset_ic: in std_logic
);
end component;
for impl: addressgroup use entity work.addressgroup(rtl);
signal clk: std_logic;
signal address_in: std_logic_vector(31 downto 0);
signal address_out: std_logic_vector(31 downto 0);
signal ic_out: std_logic_vector(31 downto 0);
signal sel_source: std_logic;
signal inc: std_logic;
signal load_ic: std_logic;
signal reset_ic: std_logic := '0';
constant period : time := 2ns;
begin
impl: addressgroup port map (clk => clk, address_in => address_in, address_out => address_out,
ic_out => ic_out, sel_source => sel_source, inc => inc, load_ic => load_ic, reset_ic => reset_ic);
process
begin
wait for 100ns;
-- 1: load ic, use ic
address_in <= "11010011110100111101001111010011";
load_ic <= '1';
inc <= '0';
sel_source <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ic_out = "11010011110100111101001111010011"
report "1 : ic_out"
severity Error;
assert address_out = "11010011110100111101001111010011"
report "1 : address_out"
severity Error;
-- 2: dont load ic, use address
address_in <= "00011110000111100001111000011110";
load_ic <= '0';
inc <= '0';
sel_source <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ic_out = "11010011110100111101001111010011"
report "2 : ic_out"
severity Error;
assert address_out = "00011110000111100001111000011110"
report "2 : address_out"
severity Error;
-- 3: inc ic, use ic
address_in <= "00011110000111100001111000011110";
load_ic <= '0';
inc <= '1';
sel_source <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ic_out = "11010011110100111101001111010100"
report "3 : ic_out"
severity Error;
assert address_out = "11010011110100111101001111010100"
report "3 : address_out"
severity Error;
-- 4: reset
address_in <= "00011110000111100001111000011110";
load_ic <= '0';
inc <= '0';
sel_source <= '1';
reset_ic <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert ic_out = "00000000000000000000000000000000"
report "4 : ic_out"
severity Error;
assert address_out = "00011110000111100001111000011110"
report "4 : address_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_system.vhd
0,0 → 1,62
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_system
--
-- PURPOSE: testbench of system entity
-- top level simulation model !!!
-- requires debugging unit to be deactivated !!!
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_system is
end tb_system;
 
architecture testbench of tb_system is
component system
port(
clk: in std_logic;
reset: in std_logic;
rs232_txd: out std_logic;
rs232_rxd: in std_logic
);
end component;
for impl: system use entity work.system(rtl);
signal clk: std_logic;
signal reset: std_logic;
signal rxd: std_logic;
signal txd: std_logic;
constant period : time := 2ns;
 
begin
impl: system port map (clk => clk, reset => reset, rs232_txd => txd, rs232_rxd => rxd);
process
begin
wait for 100ns;
-- reset
reset <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
reset <= '0';
-- start
for i in 0 to 420000000 loop
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
end loop;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_flaggroup.vhd
0,0 → 1,129
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_flaggroup
--
-- PURPOSE: testbench of flaggroup entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_flaggroup is
end tb_flaggroup;
 
architecture testbench of tb_flaggroup is
component flaggroup
port(
clk: in std_logic;
c_in: in std_logic;
z_in: in std_logic;
c_out: out std_logic;
z_out: out std_logic;
load_c: in std_logic;
load_z: in std_logic;
sel_c: in std_logic_vector(1 downto 0);
sel_z: in std_logic_vector(1 downto 0)
);
end component;
for impl: flaggroup use entity work.flaggroup(rtl);
signal clk: std_logic;
signal c_in: std_logic;
signal z_in: std_logic;
signal c_out: std_logic;
signal z_out: std_logic;
signal load_c: std_logic;
signal load_z: std_logic;
signal sel_c: std_logic_vector(1 downto 0);
signal sel_z: std_logic_vector(1 downto 0);
constant period : time := 2ns;
begin
impl: flaggroup port map (clk => clk, c_in => c_in, z_in => z_in, c_out => c_out,
z_out => z_out, load_c => load_c, load_z => load_z, sel_c => sel_c, sel_z => sel_z);
process
begin
wait for 100ns;
-- set c, clear z
sel_c <= "11";
sel_z <= "10";
load_c <= '1';
load_z <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert c_out = '1'
report "set c, clear z : c_out"
severity Error;
 
assert z_out = '0'
report "set c, clear z : z_out"
severity Error;
 
-- clear c, set z
sel_c <= "10";
sel_z <= "11";
load_c <= '1';
load_z <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert c_out = '0'
report "clear c, set z : c_out"
severity Error;
 
assert z_out = '1'
report "clear c, set z : z_out"
severity Error;
-- load c, read z
c_in <= '1';
z_in <= '0';
sel_c <= "00";
sel_z <= "00";
load_c <= '1';
load_z <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert c_out = '1'
report "load c, read z : c_out"
severity Error;
 
assert z_out = '1'
report "load c, read z : z_out"
severity Error;
-- read c, load z
c_in <= '0';
z_in <= '0';
sel_c <= "00";
sel_z <= "00";
load_c <= '0';
load_z <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert c_out = '1'
report "read c, load z : c_out"
severity Error;
 
assert z_out = '0'
report "read c, load z : z_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_vector_register.vhd
0,0 → 1,197
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_vector_register
--
-- PURPOSE: testbench of vector_register entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_vector_register is
end tb_vector_register;
 
architecture testbench of tb_vector_register is
component vector_register
generic (
n : integer range 1 to 256;
slicenr : natural
);
port (
clk: in std_logic;
r_in: in std_logic_vector(31 downto 0);
v_out: out std_logic_vector(31 downto 0);
w_out: out std_logic_vector(31 downto 0);
load_r: in std_logic;
load_select: in std_logic;
k_in: in std_logic_vector(31 downto 0);
select_v: in std_logic_vector(7 downto 0);
select_w: in std_logic_vector(2 downto 0);
select_r: in std_logic_vector(7 downto 0)
);
end component;
for impl: vector_register use entity work.vector_register(rtl);
constant n: integer range 0 to 256 := 4;
constant slicenr: natural := 2;
signal clk: std_logic;
signal r_in: std_logic_vector(31 downto 0);
signal v_out: std_logic_vector(31 downto 0);
signal w_out: std_logic_vector(31 downto 0);
signal k_in: std_logic_vector(31 downto 0);
signal load_r: std_logic;
signal load_select: std_logic;
signal select_v: std_logic_vector(7 downto 0) := "00000000";
signal select_w: std_logic_vector(2 downto 0) := "000";
signal select_r: std_logic_vector(7 downto 0) := "00000000";
constant period : time := 2ns;
begin
impl: vector_register generic map (n => n, slicenr => slicenr)
port map (clk => clk, r_in => r_in, v_out => v_out, w_out => w_out,
load_r => load_r, load_select => load_select, k_in => k_in, select_v =>
select_v, select_w => select_w, select_r => select_r);
process
begin
wait for 100ns;
-- 1: load 00000000, v_out = 00000000, w_out = 00000000
r_in <= "11010010110111101101001011011110";
select_r <= "00000000";
select_v <= "00000000";
select_w <= "000";
load_r <= '1';
load_select <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11010010110111101101001011011110"
report "1 : v_out"
severity Error;
assert w_out = "11010010110111101101001011011110"
report "1 : w_out"
severity Error;
-- 2: load 00000001, v_out = 00000000, w_out = 00000001
r_in <= "10010011001110101001001100111010";
select_r <= "00000001";
select_v <= "00000000";
select_w <= "001";
load_r <= '1';
load_select <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11010010110111101101001011011110"
report "2 : v_out"
severity Error;
assert w_out = "10010011001110101001001100111010"
report "2 : w_out"
severity Error;
-- 3: load 00000010, v_out = 00000010, w_out = 00000000
r_in <= "11110001110000111111000111000011";
select_r <= "00000010";
select_v <= "00000010";
select_w <= "000";
load_r <= '1';
load_select <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11110001110000111111000111000011"
report "3 : v_out"
severity Error;
assert w_out = "11010010110111101101001011011110"
report "3 : w_out"
severity Error;
-- 4: load 00000011, v_out = 00000000, w_out = 00000010
r_in <= "00011110000111100001111000011110";
select_r <= "00000011";
select_v <= "00000000";
select_w <= "010";
load_r <= '1';
load_select <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11010010110111101101001011011110"
report "4 : v_out"
severity Error;
assert w_out = "11110001110000111111000111000011"
report "4 : w_out"
severity Error;
-- 5: load 00000000, set slicenr wrong
r_in <= "11111111000000001111111100000000";
select_r <= "00000000";
select_v <= "00000000";
select_w <= "010";
k_in <= "00000000000000000000000000000000";
load_r <= '1';
load_select <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11010010110111101101001011011110"
report "5 : v_out"
severity Error;
assert w_out = "11110001110000111111000111000011"
report "5 : w_out"
severity Error;
-- 6: load 00000000, set slicenr properly
r_in <= "11111111000000001111111100000000";
select_r <= "00000000";
select_v <= "00000000";
select_w <= "010";
k_in <= "00000000000000000000000000000010";
load_r <= '1';
load_select <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert v_out = "11111111000000001111111100000000"
report "6 : v_out"
severity Error;
assert w_out = "11110001110000111111000111000011"
report "6 : w_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_vector_alu_32.vhd
0,0 → 1,553
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_vector_alu_32
--
-- PURPOSE: testbench of vector_alu_32 entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION:
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_vector_alu_32 is
end tb_vector_alu_32;
 
architecture testbench of tb_vector_alu_32 is
component vector_alu_32
port (
clk: in std_logic;
v_in: in std_logic_vector(31 downto 0);
w_in: in std_logic_vector(31 downto 0);
carry_in: in std_logic;
rshift_in: in std_logic;
carry_out: out std_logic;
valu_out: out std_logic_vector(31 downto 0);
valuop: in std_logic_vector(3 downto 0);
source_sel: in std_logic_vector(1 downto 0);
carry_sel: in std_logic_vector(1 downto 0);
mult_source_sel: in std_logic_vector(1 downto 0);
mult_dest_sel: in std_logic_vector(1 downto 0);
reg_input_sel: in std_logic;
load_lsr: in std_logic;
load_other: in std_logic
);
end component;
component valu_controlunit
port(
clk: in std_logic;
valu_go: in std_logic;
valuop: in std_logic_vector(3 downto 0);
vwidth: in std_logic_vector(1 downto 0);
source_sel: out std_logic_vector(1 downto 0);
carry_sel: out std_logic_vector(1 downto 0);
mult_source_sel: out std_logic_vector(1 downto 0);
mult_dest_sel: out std_logic_vector(1 downto 0);
reg_input_sel: out std_logic;
load_lsr: out std_logic;
load_other: out std_logic;
out_valid: out std_logic
);
end component;
for valu_controlunit_impl: valu_controlunit use entity work.valu_controlunit(rtl);
for alu_impl: vector_alu_32 use entity work.vector_alu_32(rtl);
signal clk: std_logic;
signal valu_go: std_logic;
signal vwidth: std_logic_vector(1 downto 0);
signal out_valid: std_logic;
signal v_in: std_logic_vector(31 downto 0);
signal w_in: std_logic_vector(31 downto 0);
signal carry_in: std_logic;
signal rshift_in: std_logic;
signal carry_out: std_logic;
signal valu_out: std_logic_vector(31 downto 0);
signal valuop: std_logic_vector(3 downto 0);
signal source_sel: std_logic_vector(1 downto 0);
signal carry_sel: std_logic_vector(1 downto 0);
signal load_lsr: std_logic;
signal load_other: std_logic;
signal mult_source_sel: std_logic_vector(1 downto 0);
signal mult_dest_sel: std_logic_vector(1 downto 0);
signal reg_input_sel: std_logic := '0';
constant period : time := 2ns;
begin
valu_controlunit_impl: valu_controlunit
port map (
clk => clk,
valu_go => valu_go,
valuop => valuop,
vwidth => vwidth,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other,
out_valid => out_valid
);
alu_impl: vector_alu_32
port map (
clk => clk,
v_in => v_in,
w_in => w_in,
carry_in => carry_in,
rshift_in => rshift_in,
carry_out => carry_out,
valu_out => valu_out,
valuop => valuop,
source_sel => source_sel,
carry_sel => carry_sel,
mult_source_sel => mult_source_sel,
mult_dest_sel => mult_dest_sel,
reg_input_sel => reg_input_sel,
load_lsr => load_lsr,
load_other => load_other
);
process
begin
wait for 100ns;
-- vadd 8_bit
v_in <= x"FE5A3415";
w_in <= x"3EBB6849";
 
carry_in <= '1';
rshift_in <= '0';
valuop <= "0000";
vwidth <= "00";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = x"3C159C5E"
report "vadd 8_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vadd 8_bit : carry_out"
severity Error;
-- vadd 16_bit
v_in <= x"F0A17E63";
w_in <= x"09C4A185";
 
carry_in <= '1';
rshift_in <= '0';
valuop <= "0000";
vwidth <= "01";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = x"FA651FE8"
report "vadd 16_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vadd 16_bit : carry_out"
severity Error;
-- vadd 32_bit
v_in <= x"F0A17E63";
w_in <= x"09C4A185";
 
carry_in <= '1';
rshift_in <= '0';
valuop <= "0000";
vwidth <= "10";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = x"FA661FE8"
report "vadd 32_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vadd 32_bit : carry_out"
severity Error;
-- vadd 64_bit
v_in <= x"F0A17E63";
w_in <= x"09C4A185";
 
carry_in <= '1';
rshift_in <= '0';
valuop <= "0000";
vwidth <= "11";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = x"FA661FE9"
report "vadd 64_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vadd 64_bit : carry_out"
severity Error;
-- vand 8_bit
v_in <= "10010100110110101110010011101011";
w_in <= "11010110101101010101010101010110";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1000";
vwidth <= "00";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "10010100100100000100010001000010"
report "vand 8_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vand 8_bit : carry_out"
severity Error;
-- vand 16_bit
v_in <= "10010100110110101110010011101011";
w_in <= "11010110101101010101010101010110";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1000";
vwidth <= "01";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "10010100100100000100010001000010"
report "vand 16_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vand 16_bit : carry_out"
severity Error;
-- vand 32_bit
v_in <= "10010100110110101110010011101011";
w_in <= "11010110101101010101010101010110";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1000";
vwidth <= "10";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "10010100100100000100010001000010"
report "vand 32_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vand 32_bit : carry_out"
severity Error;
-- vand 64_bit
v_in <= "10010100110110101110010011101011";
w_in <= "11010110101101010101010101010110";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1000";
vwidth <= "11";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "10010100100100000100010001000010"
report "vand 64_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vand 64_bit : carry_out"
severity Error;
-- vlsl 8_bit
v_in <= "10010101001100100101101110111011";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1100";
vwidth <= "00";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "00101010011001001011011001110110"
report "vlsl 8_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsl 8_bit : carry_out"
severity Error;
-- vlsl 16_bit
v_in <= "10010101001100100101101110111011";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1100";
vwidth <= "01";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "00101010011001001011011101110110"
report "vlsl 16_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsl 16_bit : carry_out"
severity Error;
-- vlsl 32_bit
v_in <= "10010101001100100101101110111011";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1100";
vwidth <= "10";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "00101010011001001011011101110110"
report "vlsl 32_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsl 32_bit : carry_out"
severity Error;
-- vlsl 64_bit
v_in <= "10010101001100100101101110111011";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1100";
vwidth <= "11";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "00101010011001001011011101110111"
report "vlsl 64_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsl 64_bit : carry_out"
severity Error;
-- vlsr 8_bit
v_in <= "10010101001100100101101110111011";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '0';
valuop <= "1110";
vwidth <= "00";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "01001010000110010010110101011101"
report "vlsr 8_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsr 8_bit : carry_out"
severity Error;
-- vlsr 16_bit
v_in <= "10010111011010110100100110010010";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '1';
valuop <= "1110";
vwidth <= "01";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "01001011101101010010010011001001"
report "vlsr 16_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vlsr 16_bit : carry_out"
severity Error;
-- vlsr 32_bit
v_in <= "11001010110101011011111110110111";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '1';
valuop <= "1110";
vwidth <= "10";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "01100101011010101101111111011011"
report "vlsr 32_bit : valu_out"
severity Error;
assert carry_out = '1'
report "vlsr 32_bit : carry_out"
severity Error;
-- vlsr 64_bit
v_in <= "00101010010110101010101001110110";
w_in <= "11111111111111111111111111111111";
carry_in <= '1';
rshift_in <= '1';
valuop <= "1110";
vwidth <= "11";
valu_go <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
valu_go <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert valu_out = "10010101001011010101010100111011"
report "vlsr 64_bit : valu_out"
severity Error;
assert carry_out = '0'
report "vlsr 64_bit : carry_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/testbenches/tb_flag.vhd
0,0 → 1,81
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: tb_flag
--
-- PURPOSE: testbench of flag entity
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
-----------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity tb_flag is
end tb_flag;
 
architecture testbench of tb_flag is
component flag
port( clk: in std_logic;
load: in std_logic;
data_in: in std_logic;
data_out: out std_logic
);
end component;
for impl: flag use entity work.flag(rtl);
signal clk: std_logic;
signal load: std_logic;
signal data_in: std_logic;
signal data_out: std_logic;
constant period : time := 2ns;
begin
impl: flag port map (clk => clk, load => load, data_in => data_in, data_out => data_out);
process
begin
wait for 100ns;
-- load 1
data_in <= '1';
load <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = '1'
report "load 1 : data_out"
severity Error;
-- not load
data_in <= '0';
load <= '0';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = '1'
report "not load : data_out"
severity Error;
-- load 2
data_in <= '0';
load <= '1';
clk <= '0'; wait for period / 2; clk <= '1'; wait for period / 2;
assert data_out = '0'
report "load 2 : data_out"
severity Error;
wait;
end process;
end;
/branches/avendor/cpu/datatypes.vhd
0,0 → 1,22
------------------------------------------------------------------
-- PROJECT: clvp (configurable lightweight vector processor)
--
-- ENTITY: datatypes
--
-- PURPOSE: definition of basic datatype
--
-- AUTHOR: harald manske, haraldmanske@gmx.de
--
-- VERSION: 1.0
------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
use work.cfg.all;
 
package datatypes is
type vectordata_type is array (k-1 downto 0) of std_logic_vector(31 downto 0);
end datatypes;
 
/branches/avendor/assembler/pyparsing.py
0,0 → 1,2942
# module pyparsing.py
#
# Copyright (c) 2003-2006 Paul T. McGuire
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
#from __future__ import generators
 
__doc__ = \
"""
pyparsing module - Classes and methods to define and execute parsing grammars
 
The pyparsing module is an alternative approach to creating and executing simple grammars,
vs. the traditional lex/yacc approach, or the use of regular expressions. With pyparsing, you
don't need to learn a new syntax for defining grammars or matching expressions - the parsing module
provides a library of classes that you use to construct the grammar directly in Python.
 
Here is a program to parse "Hello, World!" (or any greeting of the form "<salutation>, <addressee>!")::
 
from pyparsing import Word, alphas
# define grammar of a greeting
greet = Word( alphas ) + "," + Word( alphas ) + "!"
hello = "Hello, World!"
print hello, "->", greet.parseString( hello )
 
The program outputs the following::
 
Hello, World! -> ['Hello', ',', 'World', '!']
 
The Python representation of the grammar is quite readable, owing to the self-explanatory
class names, and the use of '+', '|' and '^' operators.
 
The parsed results returned from parseString() can be accessed as a nested list, a dictionary, or an
object with named attributes.
 
The pyparsing module handles some of the problems that are typically vexing when writing text parsers:
- extra or missing whitespace (the above program will also handle "Hello,World!", "Hello , World !", etc.)
- quoted strings
- embedded comments
"""
__version__ = "1.4.4-Mod-HaraldManske"
__versionTime__ = "19 October 2006 23:11"
__author__ = "Paul McGuire <ptmcg@users.sourceforge.net>"
 
 
#Modified by Harald Manske:
# - removed Deprication Warning of Upcase class
# - created Downcase class
 
import string
import copy,sys
import warnings
import re
import sre_constants
import xml.sax.saxutils
#~ sys.stderr.write( "testing pyparsing module, version %s, %s\n" % (__version__,__versionTime__ ) )
 
def _ustr(obj):
"""Drop-in replacement for str(obj) that tries to be Unicode friendly. It first tries
str(obj). If that fails with a UnicodeEncodeError, then it tries unicode(obj). It
then < returns the unicode object | encodes it with the default encoding | ... >.
"""
try:
# If this works, then _ustr(obj) has the same behaviour as str(obj), so
# it won't break any existing code.
return str(obj)
except UnicodeEncodeError, e:
# The Python docs (http://docs.python.org/ref/customization.html#l2h-182)
# state that "The return value must be a string object". However, does a
# unicode object (being a subclass of basestring) count as a "string
# object"?
# If so, then return a unicode object:
return unicode(obj)
# Else encode it... but how? There are many choices... :)
# Replace unprintables with escape codes?
#return unicode(obj).encode(sys.getdefaultencoding(), 'backslashreplace_errors')
# Replace unprintables with question marks?
#return unicode(obj).encode(sys.getdefaultencoding(), 'replace')
# ...
 
def _str2dict(strg):
return dict( [(c,0) for c in strg] )
#~ return set( [c for c in strg] )
 
class _Constants(object):
pass
alphas = string.lowercase + string.uppercase
nums = string.digits
hexnums = nums + "ABCDEFabcdef"
alphanums = alphas + nums
 
class ParseBaseException(Exception):
"""base exception class for all parsing runtime exceptions"""
__slots__ = ( "loc","msg","pstr","parserElement" )
# Performance tuning: we construct a *lot* of these, so keep this
# constructor as small and fast as possible
def __init__( self, pstr, loc, msg, elem=None ):
self.loc = loc
self.msg = msg
self.pstr = pstr
self.parserElement = elem
 
def __getattr__( self, aname ):
"""supported attributes by name are:
- lineno - returns the line number of the exception text
- col - returns the column number of the exception text
- line - returns the line containing the exception text
"""
if( aname == "lineno" ):
return lineno( self.loc, self.pstr )
elif( aname in ("col", "column") ):
return col( self.loc, self.pstr )
elif( aname == "line" ):
return line( self.loc, self.pstr )
else:
raise AttributeError, aname
 
def __str__( self ):
return "%s (at char %d), (line:%d, col:%d)" % ( self.msg, self.loc, self.lineno, self.column )
def __repr__( self ):
return _ustr(self)
def markInputline( self, markerString = ">!<" ):
"""Extracts the exception line from the input string, and marks
the location of the exception with a special symbol.
"""
line_str = self.line
line_column = self.column - 1
if markerString:
line_str = "".join( [line_str[:line_column], markerString, line_str[line_column:]])
return line_str.strip()
 
class ParseException(ParseBaseException):
"""exception thrown when parse expressions don't match class"""
"""supported attributes by name are:
- lineno - returns the line number of the exception text
- col - returns the column number of the exception text
- line - returns the line containing the exception text
"""
pass
class ParseFatalException(ParseBaseException):
"""user-throwable exception thrown when inconsistent parse content
is found; stops all parsing immediately"""
pass
 
class ReparseException(ParseBaseException):
def __init_( self, newstring, restartLoc ):
self.newParseText = newstring
self.reparseLoc = restartLoc
 
 
class RecursiveGrammarException(Exception):
"""exception thrown by validate() if the grammar could be improperly recursive"""
def __init__( self, parseElementList ):
self.parseElementTrace = parseElementList
def __str__( self ):
return "RecursiveGrammarException: %s" % self.parseElementTrace
 
class ParseResults(object):
"""Structured parse results, to provide multiple means of access to the parsed data:
- as a list (len(results))
- by list index (results[0], results[1], etc.)
- by attribute (results.<resultsName>)
"""
__slots__ = ( "__toklist", "__tokdict", "__doinit", "__name", "__parent", "__accumNames" )
def __new__(cls, toklist, name=None, asList=True, modal=True ):
if isinstance(toklist, cls):
return toklist
retobj = object.__new__(cls)
retobj.__doinit = True
return retobj
# Performance tuning: we construct a *lot* of these, so keep this
# constructor as small and fast as possible
def __init__( self, toklist, name=None, asList=True, modal=True ):
if self.__doinit:
self.__doinit = False
self.__name = None
self.__parent = None
self.__accumNames = {}
if isinstance(toklist, list):
self.__toklist = toklist[:]
else:
self.__toklist = [toklist]
self.__tokdict = dict()
 
# this line is related to debugging the asXML bug
#~ asList = False
if name:
if not modal:
self.__accumNames[name] = 0
if isinstance(name,int):
name = _ustr(name) # will always return a str, but use _ustr for consistency
self.__name = name
if not toklist in (None,'',[]):
if isinstance(toklist,basestring):
toklist = [ toklist ]
if asList:
if isinstance(toklist,ParseResults):
self[name] = (toklist.copy(),-1)
else:
self[name] = (ParseResults(toklist[0]),-1)
self[name].__name = name
else:
try:
self[name] = toklist[0]
except (KeyError,TypeError):
self[name] = toklist
 
def __getitem__( self, i ):
if isinstance( i, (int,slice) ):
return self.__toklist[i]
else:
if i not in self.__accumNames:
return self.__tokdict[i][-1][0]
else:
return ParseResults([ v[0] for v in self.__tokdict[i] ])
 
def __setitem__( self, k, v ):
if isinstance(v,tuple):
self.__tokdict[k] = self.__tokdict.get(k,list()) + [v]
sub = v[0]
elif isinstance(k,int):
self.__toklist[k] = v
sub = v
else:
self.__tokdict[k] = self.__tokdict.get(k,list()) + [(v,0)]
sub = v
if isinstance(sub,ParseResults):
sub.__parent = self
def __delitem__( self, i ):
if isinstance(i,(int,slice)):
del self.__toklist[i]
else:
del self._tokdict[i]
 
def __contains__( self, k ):
return self.__tokdict.has_key(k)
def __len__( self ): return len( self.__toklist )
def __nonzero__( self ): return len( self.__toklist ) > 0
def __iter__( self ): return iter( self.__toklist )
def keys( self ):
"""Returns all named result keys."""
return self.__tokdict.keys()
def items( self ):
"""Returns all named result keys and values as a list of tuples."""
return [(k,self[k]) for k in self.__tokdict.keys()]
def values( self ):
"""Returns all named result values."""
return [ v[-1][0] for v in self.__tokdict.values() ]
 
def __getattr__( self, name ):
if name not in self.__slots__:
if self.__tokdict.has_key( name ):
if name not in self.__accumNames:
return self.__tokdict[name][-1][0]
else:
return ParseResults([ v[0] for v in self.__tokdict[name] ])
else:
return ""
return None
 
def __add__( self, other ):
ret = self.copy()
ret += other
return ret
def __iadd__( self, other ):
if other.__tokdict:
offset = len(self.__toklist)
addoffset = ( lambda a: (a<0 and offset) or (a+offset) )
otheritems = other.__tokdict.items()
otherdictitems = [(k,(v[0],addoffset(v[1])) ) for (k,vlist) in otheritems for v in vlist]
for k,v in otherdictitems:
self[k] = v
if isinstance(v[0],ParseResults):
v[0].__parent = self
self.__toklist += other.__toklist
self.__accumNames.update( other.__accumNames )
del other
return self
def __repr__( self ):
return "(%s, %s)" % ( repr( self.__toklist ), repr( self.__tokdict ) )
 
def __str__( self ):
out = "["
sep = ""
for i in self.__toklist:
if isinstance(i, ParseResults):
out += sep + _ustr(i)
else:
out += sep + repr(i)
sep = ", "
out += "]"
return out
 
def _asStringList( self, sep='' ):
out = []
for item in self.__toklist:
if out and sep:
out.append(sep)
if isinstance( item, ParseResults ):
out += item._asStringList()
else:
out.append( _ustr(item) )
return out
 
def asList( self ):
"""Returns the parse results as a nested list of matching tokens, all converted to strings."""
out = []
for res in self.__toklist:
if isinstance(res,ParseResults):
out.append( res.asList() )
else:
out.append( res )
return out
 
def asDict( self ):
"""Returns the named parse results as dictionary."""
return dict( self.items() )
 
def copy( self ):
"""Returns a new copy of a ParseResults object."""
ret = ParseResults( self.__toklist )
ret.__tokdict = self.__tokdict.copy()
ret.__parent = self.__parent
ret.__accumNames.update( self.__accumNames )
ret.__name = self.__name
return ret
def asXML( self, doctag=None, namedItemsOnly=False, indent="", formatted=True ):
"""Returns the parse results as XML. Tags are created for tokens and lists that have defined results names."""
nl = "\n"
out = []
namedItems = dict( [ (v[1],k) for (k,vlist) in self.__tokdict.items() for v in vlist ] )
nextLevelIndent = indent + " "
# collapse out indents if formatting is not desired
if not formatted:
indent = ""
nextLevelIndent = ""
nl = ""
selfTag = None
if doctag is not None:
selfTag = doctag
else:
if self.__name:
selfTag = self.__name
if not selfTag:
if namedItemsOnly:
return ""
else:
selfTag = "ITEM"
out += [ nl, indent, "<", selfTag, ">" ]
worklist = self.__toklist
for i,res in enumerate(worklist):
if isinstance(res,ParseResults):
if i in namedItems:
out += [ res.asXML(namedItems[i], namedItemsOnly and doctag is None, nextLevelIndent,formatted)]
else:
out += [ res.asXML(None, namedItemsOnly and doctag is None, nextLevelIndent,formatted)]
else:
# individual token, see if there is a name for it
resTag = None
if i in namedItems:
resTag = namedItems[i]
if not resTag:
if namedItemsOnly:
continue
else:
resTag = "ITEM"
xmlBodyText = xml.sax.saxutils.escape(_ustr(res))
out += [ nl, nextLevelIndent, "<", resTag, ">", xmlBodyText, "</", resTag, ">" ]
out += [ nl, indent, "</", selfTag, ">" ]
return "".join(out)
 
def __lookup(self,sub):
for k,vlist in self.__tokdict.items():
for v,loc in vlist:
if sub is v:
return k
return None
def getName(self):
"""Returns the results name for this token expression."""
if self.__name:
return self.__name
elif self.__parent:
par = self.__parent
if par:
return par.__lookup(self)
else:
return None
elif (len(self) == 1 and
len(self.__tokdict) == 1 and
self.__tokdict.values()[0][0][1] in (0,-1)):
return self.__tokdict.keys()[0]
else:
return None
def dump(self,indent='',depth=0):
"""Diagnostic method for listing out the contents of a ParseResults.
Accepts an optional indent argument so that this string can be embedded
in a nested display of other data."""
out = []
out.append( indent+str(self.asList()) )
keys = self.items()
keys.sort()
for k,v in keys:
if out:
out.append('\n')
out.append( "%s%s- %s: " % (indent,(' '*depth), k) )
if isinstance(v,ParseResults):
if v.keys():
#~ out.append('\n')
out.append( v.dump(indent,depth+1) )
#~ out.append('\n')
else:
out.append(str(v))
else:
out.append(str(v))
#~ out.append('\n')
return "".join(out)
def col (loc,strg):
"""Returns current column within a string, counting newlines as line separators.
The first column is number 1.
"""
return (loc<len(strg) and strg[loc] == '\n') and 1 or loc - strg.rfind("\n", 0, loc)
 
def lineno(loc,strg):
"""Returns current line number within a string, counting newlines as line separators.
The first line is number 1.
"""
return strg.count("\n",0,loc) + 1
 
def line( loc, strg ):
"""Returns the line of text containing loc within a string, counting newlines as line separators.
"""
lastCR = strg.rfind("\n", 0, loc)
nextCR = strg.find("\n", loc)
if nextCR > 0:
return strg[lastCR+1:nextCR]
else:
return strg[lastCR+1:]
 
def _defaultStartDebugAction( instring, loc, expr ):
print "Match",expr,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )
 
def _defaultSuccessDebugAction( instring, startloc, endloc, expr, toks ):
print "Matched",expr,"->",toks.asList()
def _defaultExceptionDebugAction( instring, loc, expr, exc ):
print "Exception raised:", exc
 
def nullDebugAction(*args):
"""'Do-nothing' debug action, to suppress debugging output during parsing."""
pass
 
class ParserElement(object):
"""Abstract base level parser element class."""
DEFAULT_WHITE_CHARS = " \n\t\r"
def setDefaultWhitespaceChars( chars ):
"""Overrides the default whitespace chars
"""
ParserElement.DEFAULT_WHITE_CHARS = chars
setDefaultWhitespaceChars = staticmethod(setDefaultWhitespaceChars)
def __init__( self, savelist=False ):
self.parseAction = list()
self.failAction = None
#~ self.name = "<unknown>" # don't define self.name, let subclasses try/except upcall
self.strRepr = None
self.resultsName = None
self.saveAsList = savelist
self.skipWhitespace = True
self.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
self.copyDefaultWhiteChars = True
self.mayReturnEmpty = False
self.keepTabs = False
self.ignoreExprs = list()
self.debug = False
self.streamlined = False
self.mayIndexError = True
self.errmsg = ""
self.modalResults = True
self.debugActions = ( None, None, None )
self.re = None
 
def copy( self ):
"""Make a copy of this ParserElement. Useful for defining different parse actions
for the same parsing pattern, using copies of the original parse element."""
cpy = copy.copy( self )
cpy.parseAction = self.parseAction[:]
cpy.ignoreExprs = self.ignoreExprs[:]
if self.copyDefaultWhiteChars:
cpy.whiteChars = ParserElement.DEFAULT_WHITE_CHARS
return cpy
 
def setName( self, name ):
"""Define name for this expression, for use in debugging."""
self.name = name
self.errmsg = "Expected " + self.name
return self
 
def setResultsName( self, name, listAllMatches=False ):
"""Define name for referencing matching tokens as a nested attribute
of the returned parse results.
NOTE: this returns a *copy* of the original ParserElement object;
this is so that the client can define a basic element, such as an
integer, and reference it in multiple places with different names.
"""
newself = self.copy()
newself.resultsName = name
newself.modalResults = not listAllMatches
return newself
 
def normalizeParseActionArgs( f ):
"""Internal method used to decorate parse actions that take fewer than 3 arguments,
so that all parse actions can be called as f(s,l,t)."""
STAR_ARGS = 4
 
try:
restore = None
if isinstance(f,type):
restore = f
f = f.__init__
if f.func_code.co_flags & STAR_ARGS:
return f
numargs = f.func_code.co_argcount
if hasattr(f,"im_self"):
numargs -= 1
if restore:
f = restore
except AttributeError:
try:
# not a function, must be a callable object, get info from the
# im_func binding of its bound __call__ method
if f.__call__.im_func.func_code.co_flags & STAR_ARGS:
return f
numargs = f.__call__.im_func.func_code.co_argcount
if hasattr(f.__call__,"im_self"):
numargs -= 1
except AttributeError:
# not a bound method, get info directly from __call__ method
if f.__call__.func_code.co_flags & STAR_ARGS:
return f
numargs = f.__call__.func_code.co_argcount
if hasattr(f.__call__,"im_self"):
numargs -= 1
 
#~ print "adding function %s with %d args" % (f.func_name,numargs)
if numargs == 3:
return f
else:
if numargs == 2:
def tmp(s,l,t):
return f(l,t)
elif numargs == 1:
def tmp(s,l,t):
return f(t)
else: #~ numargs == 0:
def tmp(s,l,t):
return f()
return tmp
normalizeParseActionArgs = staticmethod(normalizeParseActionArgs)
def setParseAction( self, *fns ):
"""Define action to perform when successfully matching parse element definition.
Parse action fn is a callable method with 0-3 arguments, called as fn(s,loc,toks),
fn(loc,toks), fn(toks), or just fn(), where:
- s = the original string being parsed
- loc = the location of the matching substring
- toks = a list of the matched tokens, packaged as a ParseResults object
If the functions in fns modify the tokens, they can return them as the return
value from fn, and the modified list of tokens will replace the original.
Otherwise, fn does not need to return any value."""
self.parseAction = map(self.normalizeParseActionArgs, list(fns))
return self
 
def addParseAction( self, *fns ):
"""Add parse action to expression's list of parse actions. See setParseAction_."""
self.parseAction += map(self.normalizeParseActionArgs, list(fns))
return self
 
def setFailAction( self, fn ):
"""Define action to perform if parsing fails at this expression.
Fail acton fn is a callable function that takes the arguments
fn(s,loc,expr,err) where:
- s = string being parsed
- loc = location where expression match was attempted and failed
- expr = the parse expression that failed
- err = the exception thrown
The function returns no value. It may throw ParseFatalException
if it is desired to stop parsing immediately."""
self.failAction = fn
return self
def skipIgnorables( self, instring, loc ):
exprsFound = True
while exprsFound:
exprsFound = False
for e in self.ignoreExprs:
try:
while 1:
loc,dummy = e._parse( instring, loc )
exprsFound = True
except ParseException:
pass
return loc
 
def preParse( self, instring, loc ):
if self.ignoreExprs:
loc = self.skipIgnorables( instring, loc )
if self.skipWhitespace:
wt = self.whiteChars
instrlen = len(instring)
while loc < instrlen and instring[loc] in wt:
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
return loc, []
 
def postParse( self, instring, loc, tokenlist ):
return tokenlist
 
#~ @profile
def _parseNoCache( self, instring, loc, doActions=True, callPreParse=True ):
debugging = ( self.debug ) #and doActions )
 
if debugging or self.failAction:
#~ print "Match",self,"at loc",loc,"(%d,%d)" % ( lineno(loc,instring), col(loc,instring) )
if (self.debugActions[0] ):
self.debugActions[0]( instring, loc, self )
if callPreParse:
preloc = self.preParse( instring, loc )
else:
preloc = loc
tokensStart = loc
try:
try:
loc,tokens = self.parseImpl( instring, preloc, doActions )
except IndexError:
raise ParseException( instring, len(instring), self.errmsg, self )
#~ except ReparseException, retryEx:
#~ pass
except ParseException, err:
#~ print "Exception raised:", err
if self.debugActions[2]:
self.debugActions[2]( instring, tokensStart, self, err )
if self.failAction:
self.failAction( instring, tokensStart, self, err )
raise
else:
if callPreParse:
preloc = self.preParse( instring, loc )
else:
preloc = loc
tokensStart = loc
if self.mayIndexError or loc >= len(instring):
try:
loc,tokens = self.parseImpl( instring, preloc, doActions )
except IndexError:
raise ParseException( instring, len(instring), self.errmsg, self )
else:
loc,tokens = self.parseImpl( instring, preloc, doActions )
tokens = self.postParse( instring, loc, tokens )
 
retTokens = ParseResults( tokens, self.resultsName, asList=self.saveAsList, modal=self.modalResults )
if self.parseAction and doActions:
if debugging:
try:
for fn in self.parseAction:
tokens = fn( instring, tokensStart, retTokens )
if tokens is not None:
retTokens = ParseResults( tokens,
self.resultsName,
asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
modal=self.modalResults )
except ParseException, err:
#~ print "Exception raised in user parse action:", err
if (self.debugActions[2] ):
self.debugActions[2]( instring, tokensStart, self, err )
raise
else:
for fn in self.parseAction:
tokens = fn( instring, tokensStart, retTokens )
if tokens is not None:
retTokens = ParseResults( tokens,
self.resultsName,
asList=self.saveAsList and isinstance(tokens,(ParseResults,list)),
modal=self.modalResults )
 
if debugging:
#~ print "Matched",self,"->",retTokens.asList()
if (self.debugActions[1] ):
self.debugActions[1]( instring, tokensStart, loc, self, retTokens )
 
return loc, retTokens
 
def tryParse( self, instring, loc ):
return self._parse( instring, loc, doActions=False )[0]
# this method gets repeatedly called during backtracking with the same arguments -
# we can cache these arguments and save ourselves the trouble of re-parsing the contained expression
def _parseCache( self, instring, loc, doActions=True, callPreParse=True ):
if doActions and self.parseAction:
return self._parseNoCache( instring, loc, doActions, callPreParse )
lookup = (self,instring,loc,callPreParse)
if lookup in ParserElement._exprArgCache:
value = ParserElement._exprArgCache[ lookup ]
if isinstance(value,Exception):
if isinstance(value,ParseBaseException):
value.loc = loc
raise value
return value
else:
try:
ParserElement._exprArgCache[ lookup ] = \
value = self._parseNoCache( instring, loc, doActions, callPreParse )
return value
except ParseBaseException, pe:
ParserElement._exprArgCache[ lookup ] = pe
raise
 
_parse = _parseNoCache
 
# argument cache for optimizing repeated calls when backtracking through recursive expressions
_exprArgCache = {}
def resetCache():
ParserElement._exprArgCache.clear()
resetCache = staticmethod(resetCache)
_packratEnabled = False
def enablePackrat():
"""Enables "packrat" parsing, which adds memoizing to the parsing logic.
Repeated parse attempts at the same string location (which happens
often in many complex grammars) can immediately return a cached value,
instead of re-executing parsing/validating code. Memoizing is done of
both valid results and parsing exceptions.
This speedup may break existing programs that use parse actions that
have side-effects. For this reason, packrat parsing is disabled when
you first import pyparsing. To activate the packrat feature, your
program must call the class method ParserElement.enablePackrat(). If
your program uses psyco to "compile as you go", you must call
enablePackrat before calling psyco.full(). If you do not do this,
Python will crash. For best results, call enablePackrat() immediately
after importing pyparsing.
"""
if not ParserElement._packratEnabled:
ParserElement._packratEnabled = True
ParserElement._parse = ParserElement._parseCache
enablePackrat = staticmethod(enablePackrat)
 
def parseString( self, instring ):
"""Execute the parse expression with the given string.
This is the main interface to the client code, once the complete
expression has been built.
"""
ParserElement.resetCache()
if not self.streamlined:
self.streamline()
#~ self.saveAsList = True
for e in self.ignoreExprs:
e.streamline()
if self.keepTabs:
loc, tokens = self._parse( instring, 0 )
else:
loc, tokens = self._parse( instring.expandtabs(), 0 )
return tokens
 
def scanString( self, instring, maxMatches=sys.maxint ):
"""Scan the input string for expression matches. Each match will return the
matching tokens, start location, and end location. May be called with optional
maxMatches argument, to clip scanning after 'n' matches are found."""
if not self.streamlined:
self.streamline()
for e in self.ignoreExprs:
e.streamline()
if not self.keepTabs:
instring = instring.expandtabs()
instrlen = len(instring)
loc = 0
preparseFn = self.preParse
parseFn = self._parse
ParserElement.resetCache()
matches = 0
while loc <= instrlen and matches < maxMatches:
try:
preloc = preparseFn( instring, loc )
nextLoc,tokens = parseFn( instring, preloc, callPreParse=False )
except ParseException:
loc = preloc+1
else:
matches += 1
yield tokens, preloc, nextLoc
loc = nextLoc
def transformString( self, instring ):
"""Extension to scanString, to modify matching text with modified tokens that may
be returned from a parse action. To use transformString, define a grammar and
attach a parse action to it that modifies the returned token list.
Invoking transformString() on a target string will then scan for matches,
and replace the matched text patterns according to the logic in the parse
action. transformString() returns the resulting transformed string."""
out = []
lastE = 0
# force preservation of <TAB>s, to minimize unwanted transformation of string, and to
# keep string locs straight between transformString and scanString
self.keepTabs = True
for t,s,e in self.scanString( instring ):
out.append( instring[lastE:s] )
if t:
if isinstance(t,ParseResults):
out += t.asList()
elif isinstance(t,list):
out += t
else:
out.append(t)
lastE = e
out.append(instring[lastE:])
return "".join(out)
 
def searchString( self, instring, maxMatches=sys.maxint ):
"""Another extension to scanString, simplifying the access to the tokens found
to match the given parse expression. May be called with optional
maxMatches argument, to clip searching after 'n' matches are found.
"""
return ParseResults([ t for t,s,e in self.scanString( instring, maxMatches ) ])
def __add__(self, other ):
"""Implementation of + operator - returns And"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return And( [ self, other ] )
 
def __radd__(self, other ):
"""Implementation of += operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other + self
 
def __or__(self, other ):
"""Implementation of | operator - returns MatchFirst"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return MatchFirst( [ self, other ] )
 
def __ror__(self, other ):
"""Implementation of |= operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other | self
 
def __xor__(self, other ):
"""Implementation of ^ operator - returns Or"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return Or( [ self, other ] )
 
def __rxor__(self, other ):
"""Implementation of ^= operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other ^ self
 
def __and__(self, other ):
"""Implementation of & operator - returns Each"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return Each( [ self, other ] )
 
def __rand__(self, other ):
"""Implementation of right-& operator"""
if isinstance( other, basestring ):
other = Literal( other )
if not isinstance( other, ParserElement ):
warnings.warn("Cannot add element of type %s to ParserElement" % type(other),
SyntaxWarning, stacklevel=2)
return other & self
 
def __invert__( self ):
"""Implementation of ~ operator - returns NotAny"""
return NotAny( self )
 
def suppress( self ):
"""Suppresses the output of this ParserElement; useful to keep punctuation from
cluttering up returned output.
"""
return Suppress( self )
 
def leaveWhitespace( self ):
"""Disables the skipping of whitespace before matching the characters in the
ParserElement's defined pattern. This is normally only used internally by
the pyparsing module, but may be needed in some whitespace-sensitive grammars.
"""
self.skipWhitespace = False
return self
 
def setWhitespaceChars( self, chars ):
"""Overrides the default whitespace chars
"""
self.skipWhitespace = True
self.whiteChars = chars
self.copyDefaultWhiteChars = False
return self
def parseWithTabs( self ):
"""Overrides default behavior to expand <TAB>s to spaces before parsing the input string.
Must be called before parseString when the input grammar contains elements that
match <TAB> characters."""
self.keepTabs = True
return self
def ignore( self, other ):
"""Define expression to be ignored (e.g., comments) while doing pattern
matching; may be called repeatedly, to define multiple comment or other
ignorable patterns.
"""
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
self.ignoreExprs.append( other )
else:
self.ignoreExprs.append( Suppress( other ) )
return self
 
def setDebugActions( self, startAction, successAction, exceptionAction ):
"""Enable display of debugging messages while doing pattern matching."""
self.debugActions = (startAction or _defaultStartDebugAction,
successAction or _defaultSuccessDebugAction,
exceptionAction or _defaultExceptionDebugAction)
self.debug = True
return self
 
def setDebug( self, flag=True ):
"""Enable display of debugging messages while doing pattern matching."""
if flag:
self.setDebugActions( _defaultStartDebugAction, _defaultSuccessDebugAction, _defaultExceptionDebugAction )
else:
self.debug = False
return self
 
def __str__( self ):
return self.name
 
def __repr__( self ):
return _ustr(self)
def streamline( self ):
self.streamlined = True
self.strRepr = None
return self
def checkRecursion( self, parseElementList ):
pass
def validate( self, validateTrace=[] ):
"""Check defined expressions for valid structure, check for infinite recursive definitions."""
self.checkRecursion( [] )
 
def parseFile( self, file_or_filename ):
"""Execute the parse expression on the given file or filename.
If a filename is specified (instead of a file object),
the entire file is opened, read, and closed before parsing.
"""
try:
file_contents = file_or_filename.read()
except AttributeError:
f = open(file_or_filename, "rb")
file_contents = f.read()
f.close()
return self.parseString(file_contents)
 
 
class Token(ParserElement):
"""Abstract ParserElement subclass, for defining atomic matching patterns."""
def __init__( self ):
super(Token,self).__init__( savelist=False )
self.myException = ParseException("",0,"",self)
 
def setName(self, name):
s = super(Token,self).setName(name)
self.errmsg = "Expected " + self.name
s.myException.msg = self.errmsg
return s
 
 
class Empty(Token):
"""An empty token, will always match."""
def __init__( self ):
super(Empty,self).__init__()
self.name = "Empty"
self.mayReturnEmpty = True
self.mayIndexError = False
 
 
class NoMatch(Token):
"""A token that will never match."""
def __init__( self ):
super(NoMatch,self).__init__()
self.name = "NoMatch"
self.mayReturnEmpty = True
self.mayIndexError = False
self.errmsg = "Unmatchable token"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
 
class Literal(Token):
"""Token to exactly match a specified string."""
def __init__( self, matchString ):
super(Literal,self).__init__()
self.match = matchString
self.matchLen = len(matchString)
try:
self.firstMatchChar = matchString[0]
except IndexError:
warnings.warn("null string passed to Literal; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.__class__ = Empty
self.name = '"%s"' % self.match
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = False
self.myException.msg = self.errmsg
self.mayIndexError = False
 
# Performance tuning: this routine gets called a *lot*
# if this is a single character match string and the first character matches,
# short-circuit as quickly as possible, and avoid calling startswith
#~ @profile
def parseImpl( self, instring, loc, doActions=True ):
if (instring[loc] == self.firstMatchChar and
(self.matchLen==1 or instring.startswith(self.match,loc)) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Keyword(Token):
"""Token to exactly match a specified string as a keyword, that is, it must be
immediately followed by a non-keyword character. Compare with Literal::
Literal("if") will match the leading 'if' in 'ifAndOnlyIf'.
Keyword("if") will not; it will only match the leading 'if in 'if x=1', or 'if(y==2)'
Accepts two optional constructor arguments in addition to the keyword string:
identChars is a string of characters that would be valid identifier characters,
defaulting to all alphanumerics + "_" and "$"; caseless allows case-insensitive
matching, default is False.
"""
DEFAULT_KEYWORD_CHARS = alphanums+"_$"
def __init__( self, matchString, identChars=DEFAULT_KEYWORD_CHARS, caseless=False ):
super(Keyword,self).__init__()
self.match = matchString
self.matchLen = len(matchString)
try:
self.firstMatchChar = matchString[0]
except IndexError:
warnings.warn("null string passed to Keyword; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.name = '"%s"' % self.match
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = False
self.myException.msg = self.errmsg
self.mayIndexError = False
self.caseless = caseless
if caseless:
self.caselessmatch = matchString.upper()
identChars = identChars.upper()
self.identChars = _str2dict(identChars)
 
def parseImpl( self, instring, loc, doActions=True ):
if self.caseless:
if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) and
(loc == 0 or instring[loc-1].upper() not in self.identChars) ):
return loc+self.matchLen, self.match
else:
if (instring[loc] == self.firstMatchChar and
(self.matchLen==1 or instring.startswith(self.match,loc)) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen] not in self.identChars) and
(loc == 0 or instring[loc-1] not in self.identChars) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
def copy(self):
c = super(Keyword,self).copy()
c.identChars = Keyword.DEFAULT_KEYWORD_CHARS
return c
def setDefaultKeywordChars( chars ):
"""Overrides the default Keyword chars
"""
Keyword.DEFAULT_KEYWORD_CHARS = chars
setDefaultKeywordChars = staticmethod(setDefaultKeywordChars)
 
 
class CaselessLiteral(Literal):
"""Token to match a specified string, ignoring case of letters.
Note: the matched results will always be in the case of the given
match string, NOT the case of the input text.
"""
def __init__( self, matchString ):
super(CaselessLiteral,self).__init__( matchString.upper() )
# Preserve the defining literal.
self.returnString = matchString
self.name = "'%s'" % self.returnString
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
 
def parseImpl( self, instring, loc, doActions=True ):
if instring[ loc:loc+self.matchLen ].upper() == self.match:
return loc+self.matchLen, self.returnString
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class CaselessKeyword(Keyword):
def __init__( self, matchString, identChars=Keyword.DEFAULT_KEYWORD_CHARS ):
super(CaselessKeyword,self).__init__( matchString, identChars, caseless=True )
 
def parseImpl( self, instring, loc, doActions=True ):
if ( (instring[ loc:loc+self.matchLen ].upper() == self.caselessmatch) and
(loc >= len(instring)-self.matchLen or instring[loc+self.matchLen].upper() not in self.identChars) ):
return loc+self.matchLen, self.match
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Word(Token):
"""Token for matching words composed of allowed character sets.
Defined with string containing all allowed initial characters,
an optional string containing allowed body characters (if omitted,
defaults to the initial character set), and an optional minimum,
maximum, and/or exact length.
"""
def __init__( self, initChars, bodyChars=None, min=1, max=0, exact=0 ):
super(Word,self).__init__()
self.initCharsOrig = initChars
self.initChars = _str2dict(initChars)
if bodyChars :
self.bodyCharsOrig = bodyChars
self.bodyChars = _str2dict(bodyChars)
else:
self.bodyCharsOrig = initChars
self.bodyChars = _str2dict(initChars)
self.maxSpecified = max > 0
 
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
if ' ' not in self.initCharsOrig+self.bodyCharsOrig and (min==1 and max==0 and exact==0):
if self.bodyCharsOrig == self.initCharsOrig:
self.reString = "[%s]+" % _escapeRegexRangeChars(self.initCharsOrig)
elif len(self.bodyCharsOrig) == 1:
self.reString = "%s[%s]*" % \
(re.escape(self.initCharsOrig),
_escapeRegexRangeChars(self.bodyCharsOrig),)
else:
self.reString = "[%s][%s]*" % \
(_escapeRegexRangeChars(self.initCharsOrig),
_escapeRegexRangeChars(self.bodyCharsOrig),)
try:
self.re = re.compile( self.reString )
except:
self.re = None
def parseImpl( self, instring, loc, doActions=True ):
if self.re:
result = self.re.match(instring,loc)
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
return loc,result.group()
if not(instring[ loc ] in self.initChars):
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
instrlen = len(instring)
bodychars = self.bodyChars
maxloc = start + self.maxLen
maxloc = min( maxloc, instrlen )
while loc < maxloc and instring[loc] in bodychars:
loc += 1
throwException = False
if loc - start < self.minLen:
throwException = True
if self.maxSpecified and loc < instrlen and instring[loc] in bodychars:
throwException = True
 
if throwException:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
def __str__( self ):
try:
return super(Word,self).__str__()
except:
pass
 
if self.strRepr is None:
def charsAsStr(s):
if len(s)>4:
return s[:4]+"..."
else:
return s
if ( self.initCharsOrig != self.bodyCharsOrig ):
self.strRepr = "W:(%s,%s)" % ( charsAsStr(self.initCharsOrig), charsAsStr(self.bodyCharsOrig) )
else:
self.strRepr = "W:(%s)" % charsAsStr(self.initCharsOrig)
 
return self.strRepr
 
 
class Regex(Token):
"""Token for matching strings that match a given regular expression.
Defined with string specifying the regular expression in a form recognized by the inbuilt Python re module.
"""
def __init__( self, pattern, flags=0):
"""The parameters pattern and flags are passed to the re.compile() function as-is. See the Python re module for an explanation of the acceptable patterns and flags."""
super(Regex,self).__init__()
if len(pattern) == 0:
warnings.warn("null string passed to Regex; use Empty() instead",
SyntaxWarning, stacklevel=2)
self.pattern = pattern
self.flags = flags
try:
self.re = re.compile(self.pattern, self.flags)
self.reString = self.pattern
except sre_constants.error,e:
warnings.warn("invalid pattern (%s) passed to Regex" % pattern,
SyntaxWarning, stacklevel=2)
raise
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
result = self.re.match(instring,loc)
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
d = result.groupdict()
ret = ParseResults(result.group())
if d:
for k in d.keys():
ret[k] = d[k]
return loc,ret
def __str__( self ):
try:
return super(Regex,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "Re:(%s)" % repr(self.pattern)
return self.strRepr
 
 
class QuotedString(Token):
"""Token for matching strings that are delimited by quoting characters.
"""
def __init__( self, quoteChar, escChar=None, escQuote=None, multiline=False, unquoteResults=True, endQuoteChar=None):
"""
Defined with the following parameters:
- quoteChar - string of one or more characters defining the quote delimiting string
- escChar - character to escape quotes, typically backslash (default=None)
- escQuote - special quote sequence to escape an embedded quote string (such as SQL's "" to escape an embedded ") (default=None)
- multiline - boolean indicating whether quotes can span multiple lines (default=False)
- unquoteResults - boolean indicating whether the matched text should be unquoted (default=True)
- endQuoteChar - string of one or more characters defining the end of the quote delimited string (default=None => same as quoteChar)
"""
super(QuotedString,self).__init__()
# remove white space from quote chars - wont work anyway
quoteChar = quoteChar.strip()
if len(quoteChar) == 0:
warnings.warn("quoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
raise SyntaxError()
if endQuoteChar is None:
endQuoteChar = quoteChar
else:
endQuoteChar = endQuoteChar.strip()
if len(endQuoteChar) == 0:
warnings.warn("endQuoteChar cannot be the empty string",SyntaxWarning,stacklevel=2)
raise SyntaxError()
self.quoteChar = quoteChar
self.quoteCharLen = len(quoteChar)
self.firstQuoteChar = quoteChar[0]
self.endQuoteChar = endQuoteChar
self.endQuoteCharLen = len(endQuoteChar)
self.escChar = escChar
self.escQuote = escQuote
self.unquoteResults = unquoteResults
if multiline:
self.flags = re.MULTILINE | re.DOTALL
self.pattern = r'%s(?:[^%s%s]' % \
( re.escape(self.quoteChar),
_escapeRegexRangeChars(self.endQuoteChar[0]),
(escChar is not None and _escapeRegexRangeChars(escChar) or '') )
else:
self.flags = 0
self.pattern = r'%s(?:[^%s\n\r%s]' % \
( re.escape(self.quoteChar),
_escapeRegexRangeChars(self.endQuoteChar[0]),
(escChar is not None and _escapeRegexRangeChars(escChar) or '') )
if len(self.endQuoteChar) > 1:
self.pattern += (
'|(?:' + ')|(?:'.join(["%s[^%s]" % (re.escape(self.endQuoteChar[:i]),
_escapeRegexRangeChars(self.endQuoteChar[i]))
for i in range(len(self.endQuoteChar)-1,0,-1)]) + ')'
)
if escQuote:
self.pattern += (r'|(?:%s)' % re.escape(escQuote))
if escChar:
self.pattern += (r'|(?:%s.)' % re.escape(escChar))
self.escCharReplacePattern = re.escape(self.escChar)+"(.)"
self.pattern += (r')*%s' % re.escape(self.endQuoteChar))
try:
self.re = re.compile(self.pattern, self.flags)
self.reString = self.pattern
except sre_constants.error,e:
warnings.warn("invalid pattern (%s) passed to Regex" % self.pattern,
SyntaxWarning, stacklevel=2)
raise
 
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
self.mayIndexError = False
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
result = instring[loc] == self.firstQuoteChar and self.re.match(instring,loc) or None
if not result:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
loc = result.end()
ret = result.group()
print ret
if self.unquoteResults:
# strip off quotes
ret = ret[self.quoteCharLen:-self.endQuoteCharLen]
if isinstance(ret,basestring):
# replace escaped characters
if self.escChar:
ret = re.sub(self.escCharReplacePattern,"\g<1>",ret)
 
# replace escaped quotes
if self.escQuote:
ret = ret.replace(self.escQuote, self.endQuoteChar)
 
return loc, ret
def __str__( self ):
try:
return super(QuotedString,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "quoted string, starting with %s ending with %s" % (self.quoteChar, self.endQuoteChar)
return self.strRepr
 
 
class CharsNotIn(Token):
"""Token for matching words composed of characters *not* in a given set.
Defined with string containing all disallowed characters, and an optional
minimum, maximum, and/or exact length.
"""
def __init__( self, notChars, min=1, max=0, exact=0 ):
super(CharsNotIn,self).__init__()
self.skipWhitespace = False
self.notChars = notChars
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
self.name = _ustr(self)
self.errmsg = "Expected " + self.name
self.mayReturnEmpty = ( self.minLen == 0 )
self.myException.msg = self.errmsg
self.mayIndexError = False
 
def parseImpl( self, instring, loc, doActions=True ):
if instring[loc] in self.notChars:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
notchars = self.notChars
maxlen = min( start+self.maxLen, len(instring) )
while loc < maxlen and \
(instring[loc] not in notchars):
loc += 1
 
if loc - start < self.minLen:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
def __str__( self ):
try:
return super(CharsNotIn, self).__str__()
except:
pass
 
if self.strRepr is None:
if len(self.notChars) > 4:
self.strRepr = "!W:(%s...)" % self.notChars[:4]
else:
self.strRepr = "!W:(%s)" % self.notChars
return self.strRepr
 
class White(Token):
"""Special matching class for matching whitespace. Normally, whitespace is ignored
by pyparsing grammars. This class is included when some whitespace structures
are significant. Define with a string containing the whitespace characters to be
matched; default is " \\t\\n". Also takes optional min, max, and exact arguments,
as defined for the Word class."""
whiteStrs = {
" " : "<SPC>",
"\t": "<TAB>",
"\n": "<LF>",
"\r": "<CR>",
"\f": "<FF>",
}
def __init__(self, ws=" \t\r\n", min=1, max=0, exact=0):
super(White,self).__init__()
self.matchWhite = ws
self.setWhitespaceChars( "".join([c for c in self.whiteChars if c not in self.matchWhite]) )
#~ self.leaveWhitespace()
self.name = ("".join([White.whiteStrs[c] for c in self.matchWhite]))
self.mayReturnEmpty = True
self.errmsg = "Expected " + self.name
self.myException.msg = self.errmsg
 
self.minLen = min
 
if max > 0:
self.maxLen = max
else:
self.maxLen = sys.maxint
 
if exact > 0:
self.maxLen = exact
self.minLen = exact
def parseImpl( self, instring, loc, doActions=True ):
if not(instring[ loc ] in self.matchWhite):
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
start = loc
loc += 1
maxloc = start + self.maxLen
maxloc = min( maxloc, len(instring) )
while loc < maxloc and instring[loc] in self.matchWhite:
loc += 1
 
if loc - start < self.minLen:
#~ raise ParseException( instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
return loc, instring[start:loc]
 
 
class PositionToken(Token):
def __init__( self ):
super(PositionToken,self).__init__()
self.name=self.__class__.__name__
self.mayReturnEmpty = True
self.mayIndexError = False
 
class GoToColumn(PositionToken):
"""Token to advance to a specific column of input text; useful for tabular report scraping."""
def __init__( self, colno ):
super(GoToColumn,self).__init__()
self.col = colno
 
def preParse( self, instring, loc ):
if col(loc,instring) != self.col:
instrlen = len(instring)
if self.ignoreExprs:
loc = self.skipIgnorables( instring, loc )
while loc < instrlen and instring[loc].isspace() and col( loc, instring ) != self.col :
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
thiscol = col( loc, instring )
if thiscol > self.col:
raise ParseException( instring, loc, "Text not in expected column", self )
newloc = loc + self.col - thiscol
ret = instring[ loc: newloc ]
return newloc, ret
 
class LineStart(PositionToken):
"""Matches if current position is at the beginning of a line within the parse string"""
def __init__( self ):
super(LineStart,self).__init__()
self.setWhitespaceChars( " \t" )
self.errmsg = "Expected start of line"
self.myException.msg = self.errmsg
 
def preParse( self, instring, loc ):
preloc = super(LineStart,self).preParse(instring,loc)
if instring[preloc] == "\n":
loc += 1
return loc
 
def parseImpl( self, instring, loc, doActions=True ):
if not( loc==0 or ( loc<len(instring) and instring[loc-1] == "\n" ) ): #col(loc, instring) != 1:
#~ raise ParseException( instring, loc, "Expected start of line" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
class LineEnd(PositionToken):
"""Matches if current position is at the end of a line within the parse string"""
def __init__( self ):
super(LineEnd,self).__init__()
self.setWhitespaceChars( " \t" )
self.errmsg = "Expected end of line"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc<len(instring):
if instring[loc] == "\n":
return loc+1, "\n"
else:
#~ raise ParseException( instring, loc, "Expected end of line" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
elif loc == len(instring):
return loc+1, []
else:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class StringStart(PositionToken):
"""Matches if current position is at the beginning of the parse string"""
def __init__( self ):
super(StringStart,self).__init__()
self.errmsg = "Expected start of text"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc != 0:
# see if entire string up to here is just whitespace and ignoreables
if loc != self.preParse( instring, 0 ):
#~ raise ParseException( instring, loc, "Expected start of text" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
class StringEnd(PositionToken):
"""Matches if current position is at the end of the parse string"""
def __init__( self ):
super(StringEnd,self).__init__()
self.errmsg = "Expected end of text"
self.myException.msg = self.errmsg
def parseImpl( self, instring, loc, doActions=True ):
if loc < len(instring):
#~ raise ParseException( instring, loc, "Expected end of text" )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
elif loc == len(instring):
return loc+1, []
else:
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
 
class ParseExpression(ParserElement):
"""Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
def __init__( self, exprs, savelist = False ):
super(ParseExpression,self).__init__(savelist)
if isinstance( exprs, list ):
self.exprs = exprs
elif isinstance( exprs, basestring ):
self.exprs = [ Literal( exprs ) ]
else:
self.exprs = [ exprs ]
 
def __getitem__( self, i ):
return self.exprs[i]
 
def append( self, other ):
self.exprs.append( other )
self.strRepr = None
return self
 
def leaveWhitespace( self ):
"""Extends leaveWhitespace defined in base class, and also invokes leaveWhitespace on
all contained expressions."""
self.skipWhitespace = False
self.exprs = [ e.copy() for e in self.exprs ]
for e in self.exprs:
e.leaveWhitespace()
return self
 
def ignore( self, other ):
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
super( ParseExpression, self).ignore( other )
for e in self.exprs:
e.ignore( self.ignoreExprs[-1] )
else:
super( ParseExpression, self).ignore( other )
for e in self.exprs:
e.ignore( self.ignoreExprs[-1] )
return self
 
def __str__( self ):
try:
return super(ParseExpression,self).__str__()
except:
pass
if self.strRepr is None:
self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.exprs) )
return self.strRepr
 
def streamline( self ):
super(ParseExpression,self).streamline()
 
for e in self.exprs:
e.streamline()
 
# collapse nested And's of the form And( And( And( a,b), c), d) to And( a,b,c,d )
# but only if there are no parse actions or resultsNames on the nested And's
# (likewise for Or's and MatchFirst's)
if ( len(self.exprs) == 2 ):
other = self.exprs[0]
if ( isinstance( other, self.__class__ ) and
not(other.parseAction) and
other.resultsName is None and
not other.debug ):
self.exprs = other.exprs[:] + [ self.exprs[1] ]
self.strRepr = None
self.mayReturnEmpty |= other.mayReturnEmpty
self.mayIndexError |= other.mayIndexError
 
other = self.exprs[-1]
if ( isinstance( other, self.__class__ ) and
not(other.parseAction) and
other.resultsName is None and
not other.debug ):
self.exprs = self.exprs[:-1] + other.exprs[:]
self.strRepr = None
self.mayReturnEmpty |= other.mayReturnEmpty
self.mayIndexError |= other.mayIndexError
 
return self
 
def setResultsName( self, name, listAllMatches=False ):
ret = super(ParseExpression,self).setResultsName(name,listAllMatches)
return ret
def validate( self, validateTrace=[] ):
tmp = validateTrace[:]+[self]
for e in self.exprs:
e.validate(tmp)
self.checkRecursion( [] )
 
class And(ParseExpression):
"""Requires all given ParseExpressions to be found in the given order.
Expressions may be separated by whitespace.
May be constructed using the '+' operator.
"""
def __init__( self, exprs, savelist = True ):
super(And,self).__init__(exprs, savelist)
self.mayReturnEmpty = True
for e in self.exprs:
if not e.mayReturnEmpty:
self.mayReturnEmpty = False
break
self.setWhitespaceChars( exprs[0].whiteChars )
self.skipWhitespace = exprs[0].skipWhitespace
 
def parseImpl( self, instring, loc, doActions=True ):
loc, resultlist = self.exprs[0]._parse( instring, loc, doActions )
for e in self.exprs[1:]:
loc, exprtokens = e._parse( instring, loc, doActions )
if exprtokens or exprtokens.keys():
resultlist += exprtokens
return loc, resultlist
 
def __iadd__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #And( [ self, other ] )
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
if not e.mayReturnEmpty:
break
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
 
class Or(ParseExpression):
"""Requires that at least one ParseExpression is found.
If two expressions match, the expression that matches the longest string will be used.
May be constructed using the '^' operator.
"""
def __init__( self, exprs, savelist = False ):
super(Or,self).__init__(exprs, savelist)
self.mayReturnEmpty = False
for e in self.exprs:
if e.mayReturnEmpty:
self.mayReturnEmpty = True
break
def parseImpl( self, instring, loc, doActions=True ):
maxExcLoc = -1
maxMatchLoc = -1
for e in self.exprs:
try:
loc2 = e.tryParse( instring, loc )
except ParseException, err:
if err.loc > maxExcLoc:
maxException = err
maxExcLoc = err.loc
except IndexError, err:
if len(instring) > maxExcLoc:
maxException = ParseException(instring,len(instring),e.errmsg,self)
maxExcLoc = len(instring)
else:
if loc2 > maxMatchLoc:
maxMatchLoc = loc2
maxMatchExp = e
if maxMatchLoc < 0:
if self.exprs:
raise maxException
else:
raise ParseException(instring, loc, "no defined alternatives to match", self)
 
return maxMatchExp._parse( instring, loc, doActions )
 
def __ixor__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #Or( [ self, other ] )
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " ^ ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
 
class MatchFirst(ParseExpression):
"""Requires that at least one ParseExpression is found.
If two expressions match, the first one listed is the one that will match.
May be constructed using the '|' operator.
"""
def __init__( self, exprs, savelist = False ):
super(MatchFirst,self).__init__(exprs, savelist)
if exprs:
self.mayReturnEmpty = False
for e in self.exprs:
if e.mayReturnEmpty:
self.mayReturnEmpty = True
break
else:
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
maxExcLoc = -1
for e in self.exprs:
try:
ret = e._parse( instring, loc, doActions )
return ret
except ParseException, err:
if err.loc > maxExcLoc:
maxException = err
maxExcLoc = err.loc
except IndexError, err:
if len(instring) > maxExcLoc:
maxException = ParseException(instring,len(instring),e.errmsg,self)
maxExcLoc = len(instring)
 
# only got here if no expression matched, raise exception for match that made it the furthest
else:
if self.exprs:
raise maxException
else:
raise ParseException(instring, loc, "no defined alternatives to match", self)
 
def __ior__(self, other ):
if isinstance( other, basestring ):
other = Literal( other )
return self.append( other ) #MatchFirst( [ self, other ] )
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " | ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
class Each(ParseExpression):
"""Requires all given ParseExpressions to be found, but in any order.
Expressions may be separated by whitespace.
May be constructed using the '&' operator.
"""
def __init__( self, exprs, savelist = True ):
super(Each,self).__init__(exprs, savelist)
self.mayReturnEmpty = True
for e in self.exprs:
if not e.mayReturnEmpty:
self.mayReturnEmpty = False
break
self.skipWhitespace = True
self.optionals = [ e.expr for e in exprs if isinstance(e,Optional) ]
self.multioptionals = [ e.expr for e in exprs if isinstance(e,ZeroOrMore) ]
self.multirequired = [ e.expr for e in exprs if isinstance(e,OneOrMore) ]
self.required = [ e for e in exprs if not isinstance(e,(Optional,ZeroOrMore,OneOrMore)) ]
self.required += self.multirequired
 
def parseImpl( self, instring, loc, doActions=True ):
tmpLoc = loc
tmpReqd = self.required[:]
tmpOpt = self.optionals[:]
matchOrder = []
 
keepMatching = True
while keepMatching:
tmpExprs = tmpReqd + tmpOpt + self.multioptionals + self.multirequired
failed = []
for e in tmpExprs:
try:
tmpLoc = e.tryParse( instring, tmpLoc )
except ParseException:
failed.append(e)
else:
matchOrder.append(e)
if e in tmpReqd:
tmpReqd.remove(e)
elif e in tmpOpt:
tmpOpt.remove(e)
if len(failed) == len(tmpExprs):
keepMatching = False
if tmpReqd:
missing = ", ".join( [ _ustr(e) for e in tmpReqd ] )
raise ParseException(instring,loc,"Missing one or more required elements (%s)" % missing )
 
resultlist = []
for e in matchOrder:
loc,results = e._parse(instring,loc,doActions)
resultlist.append(results)
finalResults = ParseResults([])
for r in resultlist:
dups = {}
for k in r.keys():
if k in finalResults.keys():
tmp = ParseResults(finalResults[k])
tmp += ParseResults(r[k])
dups[k] = tmp
finalResults += ParseResults(r)
for k,v in dups.items():
finalResults[k] = v
return loc, finalResults
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + " & ".join( [ _ustr(e) for e in self.exprs ] ) + "}"
return self.strRepr
def checkRecursion( self, parseElementList ):
subRecCheckList = parseElementList[:] + [ self ]
for e in self.exprs:
e.checkRecursion( subRecCheckList )
 
 
class ParseElementEnhance(ParserElement):
"""Abstract subclass of ParserElement, for combining and post-processing parsed tokens."""
def __init__( self, expr, savelist=False ):
super(ParseElementEnhance,self).__init__(savelist)
if isinstance( expr, basestring ):
expr = Literal(expr)
self.expr = expr
self.strRepr = None
if expr is not None:
self.mayIndexError = expr.mayIndexError
self.setWhitespaceChars( expr.whiteChars )
self.skipWhitespace = expr.skipWhitespace
self.saveAsList = expr.saveAsList
def parseImpl( self, instring, loc, doActions=True ):
if self.expr is not None:
return self.expr._parse( instring, loc, doActions )
else:
raise ParseException("",loc,self.errmsg,self)
def leaveWhitespace( self ):
self.skipWhitespace = False
self.expr = self.expr.copy()
if self.expr is not None:
self.expr.leaveWhitespace()
return self
 
def ignore( self, other ):
if isinstance( other, Suppress ):
if other not in self.ignoreExprs:
super( ParseElementEnhance, self).ignore( other )
if self.expr is not None:
self.expr.ignore( self.ignoreExprs[-1] )
else:
super( ParseElementEnhance, self).ignore( other )
if self.expr is not None:
self.expr.ignore( self.ignoreExprs[-1] )
return self
 
def streamline( self ):
super(ParseElementEnhance,self).streamline()
if self.expr is not None:
self.expr.streamline()
return self
 
def checkRecursion( self, parseElementList ):
if self in parseElementList:
raise RecursiveGrammarException( parseElementList+[self] )
subRecCheckList = parseElementList[:] + [ self ]
if self.expr is not None:
self.expr.checkRecursion( subRecCheckList )
def validate( self, validateTrace=[] ):
tmp = validateTrace[:]+[self]
if self.expr is not None:
self.expr.validate(tmp)
self.checkRecursion( [] )
def __str__( self ):
try:
return super(ParseElementEnhance,self).__str__()
except:
pass
if self.strRepr is None and self.expr is not None:
self.strRepr = "%s:(%s)" % ( self.__class__.__name__, _ustr(self.expr) )
return self.strRepr
 
 
class FollowedBy(ParseElementEnhance):
"""Lookahead matching of the given parse expression. FollowedBy
does *not* advance the parsing position within the input string, it only
verifies that the specified parse expression matches at the current
position. FollowedBy always returns a null token list."""
def __init__( self, expr ):
super(FollowedBy,self).__init__(expr)
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
self.expr.tryParse( instring, loc )
return loc, []
 
 
class NotAny(ParseElementEnhance):
"""Lookahead to disallow matching with the given parse expression. NotAny
does *not* advance the parsing position within the input string, it only
verifies that the specified parse expression does *not* match at the current
position. Also, NotAny does *not* skip over leading whitespace. NotAny
always returns a null token list. May be constructed using the '~' operator."""
def __init__( self, expr ):
super(NotAny,self).__init__(expr)
#~ self.leaveWhitespace()
self.skipWhitespace = False # do NOT use self.leaveWhitespace(), don't want to propagate to exprs
self.mayReturnEmpty = True
self.errmsg = "Found unwanted token, "+_ustr(self.expr)
self.myException = ParseException("",0,self.errmsg,self)
def parseImpl( self, instring, loc, doActions=True ):
try:
self.expr.tryParse( instring, loc )
except (ParseException,IndexError):
pass
else:
#~ raise ParseException(instring, loc, self.errmsg )
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
return loc, []
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "~{" + _ustr(self.expr) + "}"
return self.strRepr
 
 
class ZeroOrMore(ParseElementEnhance):
"""Optional repetition of zero or more of the given expression."""
def __init__( self, expr ):
super(ZeroOrMore,self).__init__(expr)
self.mayReturnEmpty = True
def parseImpl( self, instring, loc, doActions=True ):
tokens = []
try:
loc, tokens = self.expr._parse( instring, loc, doActions )
hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
while 1:
if hasIgnoreExprs:
preloc = self.skipIgnorables( instring, loc )
else:
preloc = loc
loc, tmptokens = self.expr._parse( instring, preloc, doActions )
if tmptokens or tmptokens.keys():
tokens += tmptokens
except (ParseException,IndexError):
pass
 
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "[" + _ustr(self.expr) + "]..."
return self.strRepr
def setResultsName( self, name, listAllMatches=False ):
ret = super(ZeroOrMore,self).setResultsName(name,listAllMatches)
ret.saveAsList = True
return ret
 
class OneOrMore(ParseElementEnhance):
"""Repetition of one or more of the given expression."""
def parseImpl( self, instring, loc, doActions=True ):
# must be at least one
loc, tokens = self.expr._parse( instring, loc, doActions )
try:
hasIgnoreExprs = ( len(self.ignoreExprs) > 0 )
while 1:
if hasIgnoreExprs:
preloc = self.skipIgnorables( instring, loc )
else:
preloc = loc
loc, tmptokens = self.expr._parse( instring, preloc, doActions )
if tmptokens or tmptokens.keys():
tokens += tmptokens
except (ParseException,IndexError):
pass
 
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "{" + _ustr(self.expr) + "}..."
return self.strRepr
def setResultsName( self, name, listAllMatches=False ):
ret = super(OneOrMore,self).setResultsName(name,listAllMatches)
ret.saveAsList = True
return ret
 
class _NullToken(object):
def __bool__(self):
return False
def __str__(self):
return ""
 
_optionalNotMatched = _NullToken()
class Optional(ParseElementEnhance):
"""Optional matching of the given expression.
A default return string can also be specified, if the optional expression
is not found.
"""
def __init__( self, exprs, default=_optionalNotMatched ):
super(Optional,self).__init__( exprs, savelist=False )
self.defaultValue = default
self.mayReturnEmpty = True
 
def parseImpl( self, instring, loc, doActions=True ):
try:
loc, tokens = self.expr._parse( instring, loc, doActions )
except (ParseException,IndexError):
if self.defaultValue is not _optionalNotMatched:
tokens = [ self.defaultValue ]
else:
tokens = []
return loc, tokens
 
def __str__( self ):
if hasattr(self,"name"):
return self.name
if self.strRepr is None:
self.strRepr = "[" + _ustr(self.expr) + "]"
return self.strRepr
 
 
class SkipTo(ParseElementEnhance):
"""Token for skipping over all undefined text until the matched expression is found.
If include is set to true, the matched expression is also consumed. The ignore
argument is used to define grammars (typically quoted strings and comments) that
might contain false matches.
"""
def __init__( self, other, include=False, ignore=None ):
super( SkipTo, self ).__init__( other )
if ignore is not None:
self.expr = self.expr.copy()
self.expr.ignore(ignore)
self.mayReturnEmpty = True
self.mayIndexError = False
self.includeMatch = include
self.asList = False
self.errmsg = "No match found for "+_ustr(self.expr)
self.myException = ParseException("",0,self.errmsg,self)
 
def parseImpl( self, instring, loc, doActions=True ):
startLoc = loc
instrlen = len(instring)
expr = self.expr
while loc <= instrlen:
try:
loc = expr.skipIgnorables( instring, loc )
expr._parse( instring, loc, doActions=False, callPreParse=False )
if self.includeMatch:
skipText = instring[startLoc:loc]
loc,mat = expr._parse(instring,loc)
if mat:
return loc, [ skipText, mat ]
else:
return loc, [ skipText ]
else:
return loc, [ instring[startLoc:loc] ]
except (ParseException,IndexError):
loc += 1
exc = self.myException
exc.loc = loc
exc.pstr = instring
raise exc
 
class Forward(ParseElementEnhance):
"""Forward declaration of an expression to be defined later -
used for recursive grammars, such as algebraic infix notation.
When the expression is known, it is assigned to the Forward variable using the '<<' operator.
Note: take care when assigning to Forward not to overlook precedence of operators.
Specifically, '|' has a lower precedence than '<<', so that::
fwdExpr << a | b | c
will actually be evaluated as::
(fwdExpr << a) | b | c
thereby leaving b and c out as parseable alternatives. It is recommended that you
explicitly group the values inserted into the Forward::
fwdExpr << (a | b | c)
"""
def __init__( self, other=None ):
super(Forward,self).__init__( other, savelist=False )
 
def __lshift__( self, other ):
if isinstance( other, basestring ):
other = Literal(other)
self.expr = other
self.mayReturnEmpty = other.mayReturnEmpty
self.strRepr = None
return self
 
def leaveWhitespace( self ):
self.skipWhitespace = False
return self
 
def streamline( self ):
if not self.streamlined:
self.streamlined = True
if self.expr is not None:
self.expr.streamline()
return self
 
def validate( self, validateTrace=[] ):
if self not in validateTrace:
tmp = validateTrace[:]+[self]
if self.expr is not None:
self.expr.validate(tmp)
self.checkRecursion([])
def __str__( self ):
if hasattr(self,"name"):
return self.name
 
self.__class__ = _ForwardNoRecurse
try:
if self.expr is not None:
retString = _ustr(self.expr)
else:
retString = "None"
finally:
self.__class__ = Forward
return "Forward: "+retString
def copy(self):
if self.expr is not None:
return super(Forward,self).copy()
else:
ret = Forward()
ret << self
return ret
 
class _ForwardNoRecurse(Forward):
def __str__( self ):
return "..."
class TokenConverter(ParseElementEnhance):
"""Abstract subclass of ParseExpression, for converting parsed results."""
def __init__( self, expr, savelist=False ):
super(TokenConverter,self).__init__( expr )#, savelist )
self.saveAsList = False
 
 
class Upcase(TokenConverter):
"""Converter to upper case all matching tokens."""
def __init__(self, *args):
super(Upcase,self).__init__(*args)
def postParse( self, instring, loc, tokenlist ):
return map( string.upper, tokenlist )
 
 
class Downcase(TokenConverter):
"""Converter to upper case all matching tokens."""
def __init__(self, *args):
super(Downcase,self).__init__(*args)
def postParse( self, instring, loc, tokenlist ):
return map( string.lower, tokenlist )
 
 
 
class Combine(TokenConverter):
"""Converter to concatenate all matching tokens to a single string.
By default, the matching patterns must also be contiguous in the input string;
this can be disabled by specifying 'adjacent=False' in the constructor.
"""
def __init__( self, expr, joinString="", adjacent=True ):
super(Combine,self).__init__( expr )
# suppress whitespace-stripping in contained parse expressions, but re-enable it on the Combine itself
if adjacent:
self.leaveWhitespace()
self.adjacent = adjacent
self.skipWhitespace = True
self.joinString = joinString
 
def ignore( self, other ):
if self.adjacent:
ParserElement.ignore(self, other)
else:
super( Combine, self).ignore( other )
return self
 
def postParse( self, instring, loc, tokenlist ):
retToks = tokenlist.copy()
del retToks[:]
retToks += ParseResults([ "".join(tokenlist._asStringList(self.joinString)) ], modal=self.modalResults)
 
if self.resultsName and len(retToks.keys())>0:
return [ retToks ]
else:
return retToks
 
class Group(TokenConverter):
"""Converter to return the matched tokens as a list - useful for returning tokens of ZeroOrMore and OneOrMore expressions."""
def __init__( self, expr ):
super(Group,self).__init__( expr )
self.saveAsList = True
 
def postParse( self, instring, loc, tokenlist ):
return [ tokenlist ]
class Dict(TokenConverter):
"""Converter to return a repetitive expression as a list, but also as a dictionary.
Each element can also be referenced using the first token in the expression as its key.
Useful for tabular report scraping when the first column can be used as a item key.
"""
def __init__( self, exprs ):
super(Dict,self).__init__( exprs )
self.saveAsList = True
 
def postParse( self, instring, loc, tokenlist ):
for i,tok in enumerate(tokenlist):
ikey = _ustr(tok[0]).strip()
if len(tok)==1:
tokenlist[ikey] = ("",i)
elif len(tok)==2 and not isinstance(tok[1],ParseResults):
tokenlist[ikey] = (tok[1],i)
else:
dictvalue = tok.copy() #ParseResults(i)
del dictvalue[0]
if len(dictvalue)!= 1 or (isinstance(dictvalue,ParseResults) and dictvalue.keys()):
tokenlist[ikey] = (dictvalue,i)
else:
tokenlist[ikey] = (dictvalue[0],i)
 
if self.resultsName:
return [ tokenlist ]
else:
return tokenlist
 
 
class Suppress(TokenConverter):
"""Converter for ignoring the results of a parsed expression."""
def postParse( self, instring, loc, tokenlist ):
return []
def suppress( self ):
return self
 
 
class OnlyOnce(object):
"""Wrapper for parse actions, to ensure they are only called once."""
def __init__(self, methodCall):
self.callable = ParserElement.normalizeParseActionArgs(methodCall)
self.called = False
def __call__(self,s,l,t):
if not self.called:
results = self.callable(s,l,t)
self.called = True
return results
raise ParseException(s,l,"")
def reset():
self.called = False
 
def traceParseAction(f):
"""Decorator for debugging parse actions."""
f = ParserElement.normalizeParseActionArgs(f)
def z(*paArgs):
thisFunc = f.func_name
s,l,t = paArgs[-3:]
if len(paArgs)>3:
thisFunc = paArgs[0].__class__.__name__ + '.' + thisFunc
sys.stderr.write( ">>entering %s(line: '%s', %d, %s)\n" % (thisFunc,line(l,s),l,t) )
try:
ret = f(*paArgs)
except Exception, exc:
sys.stderr.write( "<<leaving %s (exception: %s)\n" % (thisFunc,exc) )
raise
sys.stderr.write( "<<leaving %s (ret: %s)\n" % (thisFunc,ret) )
return ret
return z
#
# global helpers
#
def delimitedList( expr, delim=",", combine=False ):
"""Helper to define a delimited list of expressions - the delimiter defaults to ','.
By default, the list elements and delimiters can have intervening whitespace, and
comments, but this can be overridden by passing 'combine=True' in the constructor.
If combine is set to True, the matching tokens are returned as a single token
string, with the delimiters included; otherwise, the matching tokens are returned
as a list of tokens, with the delimiters suppressed.
"""
dlName = _ustr(expr)+" ["+_ustr(delim)+" "+_ustr(expr)+"]..."
if combine:
return Combine( expr + ZeroOrMore( delim + expr ) ).setName(dlName)
else:
return ( expr + ZeroOrMore( Suppress( delim ) + expr ) ).setName(dlName)
 
def countedArray( expr ):
"""Helper to define a counted list of expressions.
This helper defines a pattern of the form::
integer expr expr expr...
where the leading integer tells how many expr expressions follow.
The matched tokens returns the array of expr tokens as a list - the leading count token is suppressed.
"""
arrayExpr = Forward()
def countFieldParseAction(s,l,t):
n = int(t[0])
arrayExpr << (n and Group(And([expr]*n)) or Group(empty))
return []
return ( Word(nums).setParseAction(countFieldParseAction) + arrayExpr )
 
def _flatten(L):
if type(L) is not list: return [L]
if L == []: return L
return _flatten(L[0]) + _flatten(L[1:])
 
def matchPreviousLiteral(expr):
"""Helper to define an expression that is indirectly defined from
the tokens matched in a previous expression, that is, it looks
for a 'repeat' of a previous expression. For example::
first = Word(nums)
second = matchPreviousLiteral(first)
matchExpr = first + ":" + second
will match "1:1", but not "1:2". Because this matches a
previous literal, will also match the leading "1:1" in "1:10".
If this is not desired, use matchPreviousExpr.
Do *not* use with packrat parsing enabled.
"""
rep = Forward()
def copyTokenToRepeater(s,l,t):
if t:
if len(t) == 1:
rep << t[0]
else:
# flatten t tokens
tflat = _flatten(t.asList())
rep << And( [ Literal(tt) for tt in tflat ] )
else:
rep << Empty()
expr.addParseAction(copyTokenToRepeater)
return rep
def matchPreviousExpr(expr):
"""Helper to define an expression that is indirectly defined from
the tokens matched in a previous expression, that is, it looks
for a 'repeat' of a previous expression. For example::
first = Word(nums)
second = matchPreviousExpr(first)
matchExpr = first + ":" + second
will match "1:1", but not "1:2". Because this matches by
expressions, will *not* match the leading "1:1" in "1:10";
the expressions are evaluated first, and then compared, so
"1" is compared with "10".
Do *not* use with packrat parsing enabled.
"""
rep = Forward()
e2 = expr.copy()
rep << e2
def copyTokenToRepeater(s,l,t):
matchTokens = _flatten(t.asList())
def mustMatchTheseTokens(s,l,t):
theseTokens = _flatten(t.asList())
if theseTokens != matchTokens:
raise ParseException("",0,"")
rep.setParseAction( mustMatchTheseTokens )
expr.addParseAction(copyTokenToRepeater)
return rep
def _escapeRegexRangeChars(s):
#~ escape these chars: ^-]
for c in r"\^-]":
s = s.replace(c,"\\"+c)
s = s.replace("\n",r"\n")
s = s.replace("\t",r"\t")
return _ustr(s)
def oneOf( strs, caseless=False, useRegex=True ):
"""Helper to quickly define a set of alternative Literals, and makes sure to do
longest-first testing when there is a conflict, regardless of the input order,
but returns a MatchFirst for best performance.
Parameters:
- strs - a string of space-delimited literals, or a list of string literals
- caseless - (default=False) - treat all literals as caseless
- useRegex - (default=True) - as an optimization, will generate a Regex
object; otherwise, will generate a MatchFirst object (if caseless=True, or
if creating a Regex raises an exception)
"""
if caseless:
isequal = ( lambda a,b: a.upper() == b.upper() )
masks = ( lambda a,b: b.upper().startswith(a.upper()) )
parseElementClass = CaselessLiteral
else:
isequal = ( lambda a,b: a == b )
masks = ( lambda a,b: b.startswith(a) )
parseElementClass = Literal
if isinstance(strs,(list,tuple)):
symbols = strs[:]
elif isinstance(strs,basestring):
symbols = strs.split()
else:
warnings.warn("Invalid argument to oneOf, expected string or list",
SyntaxWarning, stacklevel=2)
i = 0
while i < len(symbols)-1:
cur = symbols[i]
for j,other in enumerate(symbols[i+1:]):
if ( isequal(other, cur) ):
del symbols[i+j+1]
break
elif ( masks(cur, other) ):
del symbols[i+j+1]
symbols.insert(i,other)
cur = other
break
else:
i += 1
 
if not caseless and useRegex:
#~ print strs,"->", "|".join( [ _escapeRegexChars(sym) for sym in symbols] )
try:
if len(symbols)==len("".join(symbols)):
return Regex( "[%s]" % "".join( [ _escapeRegexRangeChars(sym) for sym in symbols] ) )
else:
return Regex( "|".join( [ re.escape(sym) for sym in symbols] ) )
except:
warnings.warn("Exception creating Regex for oneOf, building MatchFirst",
SyntaxWarning, stacklevel=2)
 
 
# last resort, just use MatchFirst
return MatchFirst( [ parseElementClass(sym) for sym in symbols ] )
 
def dictOf( key, value ):
"""Helper to easily and clearly define a dictionary by specifying the respective patterns
for the key and value. Takes care of defining the Dict, ZeroOrMore, and Group tokens
in the proper order. The key pattern can include delimiting markers or punctuation,
as long as they are suppressed, thereby leaving the significant key text. The value
pattern can include named results, so that the Dict results can include named token
fields.
"""
return Dict( ZeroOrMore( Group ( key + value ) ) )
 
_bslash = "\\"
printables = "".join( [ c for c in string.printable if c not in string.whitespace ] )
 
# convenience constants for positional expressions
empty = Empty().setName("empty")
lineStart = LineStart().setName("lineStart")
lineEnd = LineEnd().setName("lineEnd")
stringStart = StringStart().setName("stringStart")
stringEnd = StringEnd().setName("stringEnd")
 
_escapedPunc = Word( _bslash, r"\[]-*.$+^?()~ ", exact=2 ).setParseAction(lambda s,l,t:t[0][1])
_printables_less_backslash = "".join([ c for c in printables if c not in r"\]" ])
_escapedHexChar = Combine( Suppress(_bslash + "0x") + Word(hexnums) ).setParseAction(lambda s,l,t:unichr(int(t[0],16)))
_escapedOctChar = Combine( Suppress(_bslash) + Word("0","01234567") ).setParseAction(lambda s,l,t:unichr(int(t[0],8)))
_singleChar = _escapedPunc | _escapedHexChar | _escapedOctChar | Word(_printables_less_backslash,exact=1)
_charRange = Group(_singleChar + Suppress("-") + _singleChar)
_reBracketExpr = "[" + Optional("^").setResultsName("negate") + Group( OneOrMore( _charRange | _singleChar ) ).setResultsName("body") + "]"
 
_expanded = lambda p: (isinstance(p,ParseResults) and ''.join([ unichr(c) for c in range(ord(p[0]),ord(p[1])+1) ]) or p)
def srange(s):
r"""Helper to easily define string ranges for use in Word construction. Borrows
syntax from regexp '[]' string range definitions::
srange("[0-9]") -> "0123456789"
srange("[a-z]") -> "abcdefghijklmnopqrstuvwxyz"
srange("[a-z$_]") -> "abcdefghijklmnopqrstuvwxyz$_"
The input string must be enclosed in []'s, and the returned string is the expanded
character set joined into a single string.
The values enclosed in the []'s may be::
a single character
an escaped character with a leading backslash (such as \- or \])
an escaped hex character with a leading '\0x' (\0x21, which is a '!' character)
an escaped octal character with a leading '\0' (\041, which is a '!' character)
a range of any of the above, separated by a dash ('a-z', etc.)
any combination of the above ('aeiouy', 'a-zA-Z0-9_$', etc.)
"""
try:
return "".join([_expanded(part) for part in _reBracketExpr.parseString(s).body])
except:
return ""
 
def replaceWith(replStr):
"""Helper method for common parse actions that simply return a literal value. Especially
useful when used with transformString().
"""
def _replFunc(*args):
return [replStr]
return _replFunc
 
def removeQuotes(s,l,t):
"""Helper parse action for removing quotation marks from parsed quoted strings.
To use, add this parse action to quoted string using::
quotedString.setParseAction( removeQuotes )
"""
return t[0][1:-1]
 
def upcaseTokens(s,l,t):
"""Helper parse action to convert tokens to upper case."""
return [ str(tt).upper() for tt in t ]
 
def downcaseTokens(s,l,t):
"""Helper parse action to convert tokens to lower case."""
return [ str(tt).lower() for tt in t ]
 
def keepOriginalText(s,startLoc,t):
import inspect
"""Helper parse action to preserve original parsed text,
overriding any nested parse actions."""
f = inspect.stack()[1][0]
try:
endloc = f.f_locals["loc"]
finally:
del f
return s[startLoc:endloc]
def _makeTags(tagStr, xml):
"""Internal helper to construct opening and closing tag expressions, given a tag name"""
tagAttrName = Word(alphanums)
if (xml):
tagAttrValue = dblQuotedString.copy().setParseAction( removeQuotes )
openTag = Suppress("<") + Keyword(tagStr) + \
Dict(ZeroOrMore(Group( tagAttrName + Suppress("=") + tagAttrValue ))) + \
Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
else:
printablesLessRAbrack = "".join( [ c for c in printables if c not in ">" ] )
tagAttrValue = quotedString.copy().setParseAction( removeQuotes ) | Word(printablesLessRAbrack)
openTag = Suppress("<") + Keyword(tagStr,caseless=True) + \
Dict(ZeroOrMore(Group( tagAttrName.setParseAction(downcaseTokens) + \
Suppress("=") + tagAttrValue ))) + \
Optional("/",default=[False]).setResultsName("empty").setParseAction(lambda s,l,t:t[0]=='/') + Suppress(">")
closeTag = Combine("</" + Keyword(tagStr,caseless=not xml) + ">")
openTag = openTag.setResultsName("start"+"".join(tagStr.replace(":"," ").title().split())).setName("<%s>" % tagStr)
closeTag = closeTag.setResultsName("end"+"".join(tagStr.replace(":"," ").title().split())).setName("</%s>" % tagStr)
return openTag, closeTag
 
def makeHTMLTags(tagStr):
"""Helper to construct opening and closing tag expressions for HTML, given a tag name"""
return _makeTags( tagStr, False )
 
def makeXMLTags(tagStr):
"""Helper to construct opening and closing tag expressions for XML, given a tag name"""
return _makeTags( tagStr, True )
 
opAssoc = _Constants()
opAssoc.LEFT = object()
opAssoc.RIGHT = object()
 
def operatorPrecedence( baseExpr, opList ):
"""Helper method for constructing grammars of expressions made up of
operators working in a precedence hierarchy. Operators may be unary or
binary, left- or right-associative. Parse actions can also be attached
to operator expressions.
Parameters:
- baseExpr - expression representing the most basic element for the nested
- opList - list of tuples, one for each operator precedence level in the expression grammar; each tuple is of the form
(opExpr, numTerms, rightLeftAssoc, parseAction), where:
- opExpr is the pyparsing expression for the operator;
may also be a string, which will be converted to a Literal
- numTerms is the number of terms for this operator (must
be 1 or 2)
- rightLeftAssoc is the indicator whether the operator is
right or left associative, using the pyparsing-defined
constants opAssoc.RIGHT and opAssoc.LEFT.
- parseAction is the parse action to be associated with
expressions matching this operator expression (the
parse action tuple member may be omitted)
"""
ret = Forward()
lastExpr = baseExpr | ( Suppress('(') + ret + Suppress(')') )
for i,operDef in enumerate(opList):
opExpr,arity,rightLeftAssoc,pa = (operDef + (None,))[:4]
thisExpr = Forward().setName("expr%d" % i)
if rightLeftAssoc == opAssoc.LEFT:
if arity == 1:
matchExpr = Group( lastExpr + opExpr )
elif arity == 2:
matchExpr = Group( lastExpr + OneOrMore( opExpr + lastExpr ) )
else:
raise ValueError, "operator must be unary (1) or binary (2)"
elif rightLeftAssoc == opAssoc.RIGHT:
if arity == 1:
# try to avoid LR with this extra test
if not isinstance(opExpr, Optional):
opExpr = Optional(opExpr)
matchExpr = FollowedBy(opExpr.expr + thisExpr) + Group( opExpr + thisExpr )
elif arity == 2:
matchExpr = Group( lastExpr + OneOrMore( opExpr + thisExpr ) )
else:
raise ValueError, "operator must be unary (1) or binary (2)"
else:
raise ValueError, "operator must indicate right or left associativity"
if pa:
matchExpr.setParseAction( pa )
thisExpr << ( matchExpr | lastExpr )
lastExpr = thisExpr
ret << lastExpr
return ret
 
alphas8bit = srange(r"[\0xc0-\0xd6\0xd8-\0xf6\0xf8-\0xfe]")
 
dblQuotedString = Regex(r'"(?:[^"\n\r\\]|(?:"")|(?:\\.))*"').setName("string enclosed in double quotes")
sglQuotedString = Regex(r"'(?:[^'\n\r\\]|(?:'')|(?:\\.))*'").setName("string enclosed in single quotes")
quotedString = Regex(r'''(?:"(?:[^"\n\r\\]|(?:"")|(?:\\.))*")|(?:'(?:[^'\n\r\\]|(?:'')|(?:\\.))*')''').setName("quotedString using single or double quotes")
 
# it's easy to get these comment structures wrong - they're very common, so may as well make them available
cStyleComment = Regex(r"/\*(?:[^*]*\*+)+?/").setName("C style comment")
 
htmlComment = Regex(r"<!--[\s\S]*?-->")
restOfLine = Regex(r".*").leaveWhitespace()
dblSlashComment = Regex(r"\/\/(\\\n|.)*").setName("// comment")
cppStyleComment = Regex(r"/(?:\*(?:[^*]*\*+)+?/|/[^\n]*(?:\n[^\n]*)*?(?:(?<!\\)|\Z))").setName("C++ style comment")
 
javaStyleComment = cppStyleComment
pythonStyleComment = Regex(r"#.*").setName("Python style comment")
_noncomma = "".join( [ c for c in printables if c != "," ] )
_commasepitem = Combine(OneOrMore(Word(_noncomma) +
Optional( Word(" \t") +
~Literal(",") + ~LineEnd() ) ) ).streamline().setName("commaItem")
commaSeparatedList = delimitedList( Optional( quotedString | _commasepitem, default="") ).setName("commaSeparatedList")
 
 
if __name__ == "__main__":
 
def test( teststring ):
print teststring,"->",
try:
tokens = simpleSQL.parseString( teststring )
tokenlist = tokens.asList()
print tokenlist
print "tokens = ", tokens
print "tokens.columns =", tokens.columns
print "tokens.tables =", tokens.tables
print tokens.asXML("SQL",True)
except ParseException, err:
print err.line
print " "*(err.column-1) + "^"
print err
print
 
selectToken = CaselessLiteral( "select" )
fromToken = CaselessLiteral( "from" )
 
ident = Word( alphas, alphanums + "_$" )
columnName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
columnNameList = Group( delimitedList( columnName ) )#.setName("columns")
tableName = delimitedList( ident, ".", combine=True ).setParseAction( upcaseTokens )
tableNameList = Group( delimitedList( tableName ) )#.setName("tables")
simpleSQL = ( selectToken + \
( '*' | columnNameList ).setResultsName( "columns" ) + \
fromToken + \
tableNameList.setResultsName( "tables" ) )
test( "SELECT * from XYZZY, ABC" )
test( "select * from SYS.XYZZY" )
test( "Select A from Sys.dual" )
test( "Select AA,BB,CC from Sys.dual" )
test( "Select A, B, C from Sys.dual" )
test( "Select A, B, C from Sys.dual" )
test( "Xelect A, B, C from Sys.dual" )
test( "Select A, B, C frox Sys.dual" )
test( "Select" )
test( "Select ^^^ frox Sys.dual" )
test( "Select A, B, C from Sys.dual, Table2 " )
/branches/avendor/assembler/cputest.txt
0,0 → 1,1645
; ************************************************************************
; * CPU validation program *
; ************************************************************************
; * Executes all possible commands of the target cpu to be sure that it *
; * works properly. *
; * *
; * If an error occurs, the processor will run into a halt command. *
; * Otherwise it will continue execution to the finish symbol and loop *
; * there infinety *
; * *
; ************************************************************************
; * Author: Harald Manske, haraldmanske@gmx.de *
; * Version: 1.0 *
; * Plattform: CLVP (Configurable Lightweight Vector Processor) *
; ************************************************************************
; configuration of the program
EQU n 8 ;requires n >= 4
EQU k 20 ;requires k = 16
EQU use_shuffle 0 ;requires shuffle unit
EQU use_mul 0 ;requires both, scalar and vector multiplicate
EQU use_vmolr 0 ;requires vmol and vmor commands (32 bit width)
JMP 0+START
HALT
 
;test data
ORG $10
DATA_V: DC $B2D463BC ; vector input data (max k=32)
DATA_V2: DC $AA67Df42
DC $A3B78EF3
DC $4E6AC974
DC $8FEE432E
DC $FF3AB876
DC $43B57621
DC $8E6AC974 ;8
DC $7FF3ACD3
DC $921BC4D1
DC $637DCF67
DC $7897AABD
DC $973EE234
DC $005C6E39
DC $A1BC7A35
DC $7FF8334E ;16
DC $A3486CDF
DC $94CA193B
DC $445E97C1
DC $8836D35E
DC $A9B2C45F
DC $97A36BFF
DC $79835987
DC $DCBEDFEA
DC $975CC213
DC $39DA322B
DC $8411DEA9
DC $FFFFFFFF
DC $129DE3AF
DC $7881D74A
DC $AA8D35A8
DC $5247877D
 
V_RES: ORG $30 ; vector result data (max k=32)
 
ORG $50
MASK_HW: DC $FFFF0000 ; mask to get only high word
CMP_VAL: DC $ABCD ; value to compare with immediate
CMP_VAL2: DC $FEDC ; value to compare with immediate
DATA_A: DC $A3BF74E5 ; operand A
DATA_B: DC $03C7A483 ; operand B
DATA_FF: DC $FFFFFFFF ; operand FF
STORE_DEST: DC $0 ; destination for store command
 
;results
AND_RES: DC $3872481 ; result: A and B
OR_RES: DC $A3FFF4E7 ; result: A or B
XOR_RES: DC $A078D066 ; result: A xor B
ADD_RES: DC $A7871968 ; result: A + B
SUB_RES: DC $9FF7D062 ; result: A - B
INC_RES: DC $A3BF74E6 ; result: A + 1
DEC_RES: DC $A3BF74E4 ; result: A - 1
LSL_RES: DC $477EE9CA ; result: lsl A
LSR_RES: DC $51DFBA72 ; result: lsr A
MUL_RES: DC $4B1E852F ; result A * B (16bit * 16bit)
 
ROL_RES: DC $477EE9CA ; result: rol A, carry not set
ROL_RES_C: DC $477EE9CB ; result: rol A, carry set
 
ROR_RES: DC $51DFBA72
ROR_RES_C: DC $D1DFBA72 ; result: ror A, carry set
 
RES_VSHUF_8L: DC $8EF3AA67 ; result: shuffle vwidth=00 low word
RES_VSHUF_8H: DC $DF42B2D4 ; result: shuffle vwidth=00 high word
;program start
START: NOP
 
;test flag commands and conditional jumps
TEST_ZERO: SEZ
JZ 0+TEST_NOTZERO
HALT
TEST_NOTZERO: CLZ
JZ 0+ERR_SCALAR
JNZ 0+TEST_CARRY
HALT
TEST_CARRY: SEC
JC 0+TEST_NOTCARRY
HALT
TEST_NOTCARRY: CLC
JC 0+ERR_SCALAR
JNC 0+TEST_FLAGS
HALT
TEST_FLAGS: SUB 0,0,1
JZ 0+ERR_SCALAR
JNC 0+ERR_SCALAR
JNZ 0+TEST_FLAGS2
HALT
TEST_FLAGS2: ADD 0,0,0
JC 0+ERR_SCALAR
JZ 0+TEST_LD
HALT
;test load operation
TEST_LD: LD A,0+CMP_VAL
JZ 0+ERR_SCALAR
SUB X,A,$ABCD
JC 0+ERR_SCALAR
JZ 0+TEST_LD2
HALT
TEST_LD2: OR Y,0,CMP_VAL
OR X,0,1
LD Y,Y+X
SUB 0,Y,$FEDC
JNZ 0+ERR_SCALAR
JZ 0+TEST_STORE
HALT
 
;test store operation
TEST_STORE: LD X,0+DATA_A
LD Y,0+DATA_B
ADD A,X,Y
ST 0+STORE_DEST,A
LD X,0+ADD_RES
LD Y,0+STORE_DEST
SUB 0,X,Y
JZ 0+TEST_STORE2
HALT
TEST_STORE2: OR A,0,$1234
OR X,0,1
OR Y,0,STORE_DEST
DEC Y,Y
ST X+Y,A
OR X,0,0
LD X,0+STORE_DEST
SUB Y,X,$1234
JNZ 0+ERR_SCALAR
 
;test arithmetic and logic operations
TEST_ADD: LD X,0+DATA_A
LD Y,0+DATA_B
ADD A,X,Y
JC 0+ERR_SCALAR
JZ 0+ERR_SCALAR
LD Y,0+ADD_RES
SUB 0,A,Y
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
LD X, 0+DATA_FF
ADD A,X,2
JNC 0+ERR_SCALAR
JZ 0+ERR_SCALAR
SUB 0,A,1
JZ 0+TEST_ADC
HALT
 
TEST_ADC: LD A,0+DATA_A
LD X,0+DATA_B
CLC
ADC Y,A,X
JZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
LD A,0+ADD_RES
SUB 0,A,Y
JNZ 0+ERR_SCALAR
LD Y,0+DATA_A
LD X,0+DATA_B
SEC
ADC A,X,Y
JZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
SUB A,A,1
LD Y,0+ADD_RES
SUB 0,A,Y
JNZ 0+ERR_SCALAR
JNC 0+TEST_SUB
HALT
TEST_SUB: LD X,0+DATA_A
LD Y,0+DATA_B
SUB A,X,Y
JC 0+ERR_SCALAR
LD X,0+SUB_RES
SUB 0,A,X
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
LD X,0+DATA_A
SUB A,Y,X
JNC 0+ERR_SCALAR
JNZ 0+TEST_SBC
HALT
 
TEST_SBC: LD A,0+DATA_A
LD Y,0+DATA_B
CLC
SUB X,A,Y
SBC A,A,Y
JZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
SUB 0,X,A
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
LD A,0+DATA_A
SEC
SBC A,A,Y
JZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
SUB X,X,1
SUB 0,A,X
JC 0+ERR_SCALAR
JZ 0+TEST_INC
HALT
 
TEST_INC: LD A,0+DATA_A
INC A,A
LD X,0+INC_RES
LD Y,0+DATA_A
ADD Y,Y,1
SUB 0,A,X
JNZ 0+ERR_SCALAR
SUB 0,A,Y
JNZ 0+ERR_SCALAR
LD A,0+DATA_FF
INC A,A
JNC 0+ERR_SCALAR
JZ 0+TEST_DEC
HALT
 
TEST_DEC: OR A,0,0
DEC A,A
JNC 0+ERR_SCALAR
JZ 0+ERR_SCALAR
LD X,0+DATA_FF
SUB 0,A,X
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
LD A,0+DATA_A
DEC A,A
LD Y,0+DEC_RES
SUB 0,A,Y
JC 0+ERR_SCALAR
JZ 0+TEST_AND
HALT
TEST_AND: LD A,0+DATA_A
LD X,0+DATA_B
AND Y,A,X
LD A,0+AND_RES
SUB 0,Y,A
JC 0+ERR_SCALAR
JNZ 0+ERR_SCALAR
LD A,0+DATA_FF
AND X,Y,A
SUB 0,Y,X
JNZ 0+ERR_SCALAR
OR Y,0,$3456
AND Y,Y,0
JZ 0+TEST_OR
HALT
 
TEST_OR: LD X,0+DATA_A
LD Y,0+DATA_B
OR A,X,Y
LD X,0+OR_RES
JZ 0+ERR_SCALAR
SUB 0,A,X
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
OR A,A,$FF
AND A,A,$FF
SUB 0,A,$FF
JC 0+ERR_SCALAR
JZ 0+TEST_XOR
HALT
TEST_XOR: LD X,0+DATA_A
LD Y,0+DATA_B
XOR A,X,Y
LD X,0+XOR_RES
SUB 0,A,X
JC 0+ERR_SCALAR
JNZ 0+ERR_SCALAR
LD Y,0+ADD_RES
XOR A,A,Y
SUB 0,A,X
JZ 0+ERR_SCALAR
XOR A,A,Y
SUB 0,A,X
JZ 0+TEST_LSL
HALT
 
TEST_LSL: LD A,0+DATA_A
LSL A,A
JNC 0+ERR_SCALAR
LD X,0+LSL_RES
SUB 0,A,X
JC 0+ERR_SCALAR
JZ 0+TEST_LSR
HALT
TEST_LSR: LD A,0+DATA_A
LSR A,A
JNC 0+ERR_SCALAR
LD X,0+LSR_RES
SUB 0,X,A
JC 0+ERR_SCALAR
JZ 0+TEST_ROL
HALT
 
TEST_ROL: CLC
LD Y,0+DATA_A
ROL A,Y
JNC 0+ERR_SCALAR
LD X,0+ROL_RES
SUB 0,A,X
JC 0+ERR_SCALAR
JNZ 0+ERR_SCALAR
SEC
LD Y,0+DATA_A
ROL A,Y
JNC 0+ERR_SCALAR
LD X,0+ROL_RES_C
SUB 0,A,X
JC 0+ERR_SCALAR
JZ 0+TEST_ROR
HALT
TEST_ROR: CLC
LD Y,0+DATA_A
ROR A,Y
JNC 0+ERR_SCALAR
LD X,0+ROR_RES
SUB 0,A,X
JC 0+ERR_SCALAR
JNZ 0+ERR_SCALAR
SEC
LD A,0+DATA_A
ROR A,A
JNC 0+ERR_SCALAR
LD X,0+ROR_RES_C
SUB 0,A,X
JC 0+ERR_SCALAR
JZ 0+TEST_JAL
HALT
 
TEST_JAL: JAL A,0+TEST_JAL2
HALT
TEST_JAL2: SUB 0,A,TEST_JAL
JNZ 0+ERR_SCALAR
JZ 0+TEST_MUL
TEST_MUL: OR A,0,use_mul
JZ 0+NO_MUL
LD X,0+DATA_A
LD Y,0+DATA_B
MUL A,X,Y
JC 0+ERR_SCALAR
JZ 0+ERR_SCALAR
LD Y,0+MUL_RES
SUB 0,A,Y
JNZ 0+ERR_SCALAR
JC 0+ERR_SCALAR
NO_MUL: JMP 0+TEST_VLD_ST
 
;test cooperative commands
TEST_VLD_ST: OR A,0,0
OR Y,0,0
VLD_ST_INIT: ST 0+V_RES,A ;init with 0
INC Y,Y
SUB 0,Y,k
JNZ 0+VLD_ST_INIT
OR A,0,DATA_V ;load
VLD R0,0+A
OR A,0,V_RES
VST 0+A,R0 ;store
OR Y,0,0
VLD_ST_LOOP: LD A,Y+V_RES ;check
LD X,Y+DATA_V
SUB 0,A,X
JNZ 0+ERR_COOP
INC Y,Y
SUB 0,Y,k
JNZ 0+VLD_ST_LOOP
JMP 0+TEST_MOV
HALT
TEST_MOV: OR A,0,0
MOV_LOOP: LD Y,A+DATA_V
MOV R1(A),Y ;scalar => vector
INC A,A
SUB 0,A,k
JNZ 0+MOV_LOOP
OR A,0,0
OR X,0,0
MOV_LOOP2: MOV X,R1(A) ;vector => scalar
LD Y,A+DATA_V
SUB 0,Y,X
JNZ 0+ERR_COOP
INC A,A
SUB 0,A,k
JNZ 0+MOV_LOOP2
JZ 0+TEST_VMOV
HALT
;test vector commands
TEST_VMOV: VMOV R0,R1
VMOV R<2>,R0
VMOV R3,R<2>
OR A,0,0
VMOV_LOOP: LD Y,A+DATA_V
MOV X,R0(A)
SUB 0,Y,X
JNZ 0+ERR_VECTOR
MOV X,R2(A)
SUB 0,Y,X
JNZ 0+ERR_VECTOR
MOV X,R3(A)
SUB 0,Y,X
JNZ 0+ERR_VECTOR
INC A,A
SUB 0,A,k
JNZ 0+VMOV_LOOP
 
TEST_MOVA: LD A,0+DATA_A
MOVA R0,A
OR X,0,V_RES
VST 0+X,R0
OR X,0,0
MOVA_LOOP: LD Y,X+V_RES
SUB 0,Y,A
JNZ 0+ERR_COOP
INC X,X
SUB 0,X,k
JNZ 0+MOVA_LOOP
;test vector alu commands
OR A,0,DATA_V
VLD R0,0+A
OR A,0,DATA_V2
VLD R1,0+A
 
TEST_VAND: VAND.DW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VAND_LOOP: LD X,A+DATA_V
LD Y,A+DATA_V2
AND X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VAND_LOOP
 
TEST_VOR: VOR.DW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VOR_LOOP: LD X,A+DATA_V
LD Y,A+DATA_V2
OR X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VOR_LOOP
 
TEST_VXOR: VXOR.DW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VXOR_LOOP: LD X,A+DATA_V
LD Y,A+DATA_V2
XOR X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VXOR_LOOP
 
TEST_VADD: VADD.DW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
;32 bit
OR A,0,0
VADD_LOOP_DW: LD X,A+DATA_V
LD Y,A+DATA_V2
ADD X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VADD_LOOP_DW
;64 bit
VADD.QW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VADD_LOOP_QW: ST 0+AKKU,A ;reset carry
OR A,0,0
ST 0+CARRY,A
LD A,0+AKKU
LD X,A+DATA_V
LD Y,A+DATA_V2
ADD X,X,Y
JNC 0+VADD_QW_NC ; save carry
ST 0+AKKU,A
OR A,0,1
ST 0+CARRY,A
LD A,0+AKKU
VADD_QW_NC: LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
 
LD X,A+DATA_V
LD Y,A+DATA_V2
ADD X,X,Y
LD Y,0+CARRY
ADD X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VADD_LOOP_QW
;16bit
VADD.W R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VADD_LOOP_W: LD X,A+DATA_V ;low word
LD Y,A+DATA_V2
ADD X,X,Y
LD Y,A+V_RES
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
LD X,A+DATA_V ;high word
LD Y,0+MASK_HW
AND X,X,Y
LD Y,A+DATA_V2
ST 0+AKKU,A
LD A,0+MASK_HW
AND Y,Y,A
LD A,0+AKKU
ADD X,X,Y
LD Y,A+V_RES
ST 0+AKKU,A
OR A,0,0
VADD_LOOP_W2: LSR X,X
LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VADD_LOOP_W2
LD A,0+AKKU
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VADD_LOOP_W
;8 bit
VADD.B R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VADD_LOOP_B: OR X,A,0
ST 0+AKKU,A
LD A,X+DATA_V
ST 0+A_REG,A
LD A,X+DATA_V2
ST 0+B_REG,A
LD A,X+V_RES
ST 0+RES_REG,A
OR A,0,0
VADD_LOOP_B2: ST 0+I,A
LD X,0+A_REG
LD Y,0+B_REG
LD A,0+RES_REG
ADD X,X,Y
AND X,X,$FF
AND A,A,$FF
SUB 0,X,A
JNZ 0+ERR_VALU
LD X,0+A_REG
LD Y,0+B_REG
LD A,0+RES_REG
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
ST 0+RES_REG,A
OR A,0,X
ST 0+A_REG,A
OR A,0,Y
ST 0+B_REG,A
LD A,0+I
INC A,A
SUB 0,A,4
JNZ 0+VADD_LOOP_B2
LD A,0+AKKU
INC A,A
SUB 0,A,k
JNZ 0+VADD_LOOP_B
 
TEST_VSUB: VSUB.DW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
;32 bit
OR A,0,0
VSUB_LOOP_DW: LD X,A+DATA_V
LD Y,A+DATA_V2
SUB X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VSUB_LOOP_DW
;64 bit
VSUB.QW R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VSUB_LOOP_QW: ST 0+AKKU,A ;reset carry
OR A,0,0
ST 0+CARRY,A
LD A,0+AKKU
LD X,A+DATA_V
LD Y,A+DATA_V2
SUB X,X,Y
JNC 0+VSUB_QW_NC ; save carry
ST 0+AKKU,A
OR A,0,1
ST 0+CARRY,A
LD A,0+AKKU
VSUB_QW_NC: LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
 
LD X,A+DATA_V
LD Y,A+DATA_V2
SUB X,X,Y
LD Y,0+CARRY
SUB X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VSUB_LOOP_QW
;16bit
VSUB.W R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VSUB_LOOP_W: LD X,A+DATA_V ;low word
LD Y,A+DATA_V2
SUB X,X,Y
LD Y,A+V_RES
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
LD X,A+DATA_V ;high word
LD Y,0+MASK_HW
AND X,X,Y
LD Y,A+DATA_V2
ST 0+AKKU,A
LD A,0+MASK_HW
AND Y,Y,A
LD A,0+AKKU
SUB X,X,Y
LD Y,A+V_RES
ST 0+AKKU,A
OR A,0,0
VSUB_LOOP_W2: LSR X,X
LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VSUB_LOOP_W2
LD A,0+AKKU
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VSUB_LOOP_W
;8 bit
VSUB.B R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VSUB_LOOP_B: OR X,A,0
ST 0+AKKU,A
LD A,X+DATA_V
ST 0+A_REG,A
LD A,X+DATA_V2
ST 0+B_REG,A
LD A,X+V_RES
ST 0+RES_REG,A
OR A,0,0
VSUB_LOOP_B2: ST 0+I,A
LD X,0+A_REG
LD Y,0+B_REG
LD A,0+RES_REG
SUB X,X,Y
AND X,X,$FF
AND A,A,$FF
SUB 0,X,A
JNZ 0+ERR_VALU
LD X,0+A_REG
LD Y,0+B_REG
LD A,0+RES_REG
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
LSR X,X
LSR Y,Y
LSR A,A
ST 0+RES_REG,A
OR A,0,X
ST 0+A_REG,A
OR A,0,Y
ST 0+B_REG,A
LD A,0+I
INC A,A
SUB 0,A,4
JNZ 0+VSUB_LOOP_B2
LD A,0+AKKU
INC A,A
SUB 0,A,k
JNZ 0+VSUB_LOOP_B
 
TEST_VLSL: VLSL.DW R2,R0
OR A,0,V_RES
VST 0+A,R2
;32 bit
OR A,0,0
VLSL_LOOP_DW: LD X,A+DATA_V
LSL X,X
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VLSL_LOOP_DW
;64 bit
VLSL.QW R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSL_LOOP_QW: ST 0+AKKU,A ;reset carry
OR A,0,0
ST 0+CARRY,A
LD A,0+AKKU
LD X,A+DATA_V
LSL X,X
JNC 0+VLSL_QW_NC ; save carry
ST 0+AKKU,A
OR A,0,1
ST 0+CARRY,A
LD A,0+AKKU
VLSL_QW_NC: LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
 
LD X,A+DATA_V
LD Y,0+CARRY
LSR Y,Y
ROL X,X
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VLSL_LOOP_QW
;16bit
VLSL.W R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSL_LOOP_W: LD X,A+DATA_V ;low word
LSL X,X
LD Y,A+V_RES
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
LD X,A+DATA_V ;high word
LD Y,0+MASK_HW
AND X,X,Y
LSL X,X
LD Y,A+V_RES
ST 0+AKKU,A
OR A,0,0
VLSL_LOOP_W2: LSR X,X
LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VLSL_LOOP_W2
LD A,0+AKKU
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VLSL_LOOP_W
;8 bit
VLSL.B R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSL_LOOP_B: OR X,A,0
ST 0+AKKU,A
LD A,X+DATA_V
ST 0+A_REG,A
LD A,X+V_RES
ST 0+RES_REG,A
OR A,0,0
VLSL_LOOP_B2: ST 0+I,A
LD X,0+A_REG
 
LD A,0+RES_REG
LSL X,X
AND X,X,$FF
AND A,A,$FF
SUB 0,X,A
JNZ 0+ERR_VALU
LD X,0+A_REG
LD A,0+RES_REG
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
ST 0+RES_REG,A
OR A,0,X
ST 0+A_REG,A
LD A,0+I
INC A,A
SUB 0,A,4
JNZ 0+VLSL_LOOP_B2
LD A,0+AKKU
INC A,A
SUB 0,A,k
JNZ 0+VLSL_LOOP_B
 
TEST_VLSR: VLSR.DW R2,R0
OR A,0,V_RES
VST 0+A,R2
;32 bit
OR A,0,0
VLSR_LOOP_DW: LD X,A+DATA_V
LSR X,X
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VLSR_LOOP_DW
 
;64 bit
VLSR.QW R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSR_LOOP_QW: ST 0+AKKU,A ;reset carry
OR A,0,0
ST 0+CARRY,A
LD A,0+AKKU
INC A,A
LD X,A+DATA_V
LSR X,X
JNC 0+VLSR_QW_NC ; save carry
ST 0+AKKU,A
OR A,0,1
ST 0+CARRY,A
LD A,0+AKKU
VLSR_QW_NC: LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
DEC A,A
 
LD X,A+DATA_V
LD Y,0+CARRY
LSR Y,Y
ROR X,X
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
INC A,A
SUB 0,A,k
JNZ 0+VLSR_LOOP_QW
;16bit
VLSR.W R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSR_LOOP_W: LD X,A+DATA_V ;low word
AND X,X,$FFFF
LSR X,X
LD Y,A+V_RES
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
LD X,A+DATA_V ;high word
LD Y,0+MASK_HW
AND X,X,Y
LSR X,X
LD Y,A+V_RES
ST 0+AKKU,A
OR A,0,0
VLSR_LOOP_W2: LSR X,X
LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VLSR_LOOP_W2
LD A,0+AKKU
AND X,X,$FFFF
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VLSR_LOOP_W
;8 bit
VLSR.B R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VLSR_LOOP_B: OR X,A,0
ST 0+AKKU,A
LD A,X+DATA_V
ST 0+A_REG,A
LD A,X+V_RES
ST 0+RES_REG,A
OR A,0,0
VLSR_LOOP_B2: ST 0+I,A
LD X,0+A_REG
LD A,0+RES_REG
AND X,X,$FF
LSR X,X
AND A,A,$FF
SUB 0,X,A
JNZ 0+ERR_VALU
LD X,0+A_REG
LD A,0+RES_REG
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
LSR X,X
LSR A,A
ST 0+RES_REG,A
OR A,0,X
ST 0+A_REG,A
LD A,0+I
INC A,A
SUB 0,A,4
JNZ 0+VLSR_LOOP_B2
LD A,0+AKKU
INC A,A
SUB 0,A,k
JNZ 0+VLSR_LOOP_B
 
;vector and scalar commands simultaneous
TEST_SIMUL: OR A,0,DATA_V
VLD R0,0+A
OR A,0,DATA_V2
VLD R1,0+A
LD X,0+DATA_A
LD Y,0+DATA_B
OR A,0,0
VADD.DW R2,R0,R1
VADD.DW R3,R0,R1 | ADD A,X,Y
VSUB.DW R3,R3,R2
OR Y,0,V_RES
VST 0+Y,R3
LD X,0+ADD_RES
SUB 0,X,A
JNZ 0+ERR_SIMUL
OR A,0,0
SIMUL_LOOP1: LD X,A+V_RES
JNZ 0+ERR_SIMUL
INC A,A
SUB 0,A,k
JNZ 0+SIMUL_LOOP1
LD X,0+DATA_A
LD Y,0+DATA_B
OR A,0,0
VXOR.DW R2,R0,R1
VXOR.DW R3,R0,R1 | SUB A,X,Y
VSUB.DW R3,R3,R2
OR Y,0,V_RES
VST 0+Y,R3
LD X,0+SUB_RES
SUB 0,X,A
JNZ 0+ERR_SIMUL
OR A,0,0
SIMUL_LOOP2: LD X,A+V_RES
JNZ 0+ERR_SIMUL
INC A,A
SUB 0,A,k
JNZ 0+SIMUL_LOOP2
LD X,0+DATA_A
LD Y,0+DATA_B
OR A,0,0
VMOV R2,R0
VMOV R3,R0 | AND A,X,Y
VSUB.DW R3,R3,R2
OR Y,0,V_RES
VST 0+Y,R3
LD X,0+AND_RES
SUB 0,X,A
JNZ 0+ERR_SIMUL
OR A,0,0
SIMUL_LOOP3: LD X,A+V_RES
JNZ 0+ERR_SIMUL
INC A,A
SUB 0,A,k
JNZ 0+SIMUL_LOOP3
TEST_VSHUF: OR A,0,use_shuffle
JZ 0+NO_SHUFFLE
OR A,0,DATA_V
VLD R0,0+A
OR A,0,DATA_V2
VLD R1,0+A
TEST_VSHUF1: VSHUF R2,R0,R1,00101000011011 ;vwidth + ssss + vn
OR A,0,V_RES
VST 0+A,R2
LD X,A+0
LD A,0+RES_VSHUF_8L
SUB 0,A,X
JNZ 0+ERR_VSHUF
OR A,0,V_RES
LD Y,A+1
LD A,0+RES_VSHUF_8H
SUB 0,A,Y
JNZ 0+ERR_VSHUF
TEST_VSHUF2: VSHUF R2,R0,R1,01110010110001 ;vwidth + ssss + vn
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
LD X,A+V_RES
OR A,0,1
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,1
LD X,A+V_RES
OR A,0,0
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,2
LD X,A+V_RES
OR A,0,4
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,3
LD X,A+V_RES
OR A,0,3
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
TEST_VSHUF3: VSHUF R2,R0,R1,10001101110010 ;vwidth + ssss + vn
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
LD X,A+V_RES
OR A,0,5
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,1
LD X,A+V_RES
OR A,0,6
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,2
LD X,A+V_RES
OR A,0,1
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,3
LD X,A+V_RES
OR A,0,2
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,4
LD X,A+V_RES
OR A,0,6
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,5
LD X,A+V_RES
OR A,0,7
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,6
LD X,A+V_RES
OR A,0,2
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,7
LD X,A+V_RES
OR A,0,3
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
TEST_VSHUF4: VSHUF R2,R0,R1,11010100100111 ;vwidth + ssss + vn
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
LD X,A+V_RES
OR A,0,13
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,1
LD X,A+V_RES
OR A,0,14
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,2
LD X,A+V_RES
OR A,0,15
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,3
LD X,A+V_RES
OR A,0,16
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
;--------------
OR A,0,4
LD X,A+V_RES
OR A,0,4
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,5
LD X,A+V_RES
OR A,0,5
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,6
LD X,A+V_RES
OR A,0,6
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,7
LD X,A+V_RES
OR A,0,7
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
;--------------
OR A,0,8
LD X,A+V_RES
OR A,0,9
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,9
LD X,A+V_RES
OR A,0,10
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,10
LD X,A+V_RES
OR A,0,11
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,11
LD X,A+V_RES
OR A,0,12
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
;--------------
OR A,0,12
LD X,A+V_RES
OR A,0,0
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,13
LD X,A+V_RES
OR A,0,1
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,14
LD X,A+V_RES
OR A,0,2
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
OR A,0,15
LD X,A+V_RES
OR A,0,3
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VSHUF
NO_SHUFFLE: NOP
 
TEST_VMUL: OR A,0,use_mul
JZ 0+NO_VMUL
;16 bit
VMUL.W R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VMUL_LOOP_W: LD X,A+DATA_V
LD Y,A+DATA_V2
MUL X,X,Y
LD Y,A+V_RES
SUB 0,X,Y
JNZ 0+ERR_VALU
INC A,A
SUB 0,A,k
JNZ 0+VMUL_LOOP_W
 
;8 bit
VMUL.B R2,R0,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VMUL_LOOP_B: LD X,A+DATA_V ;high word
LD Y,A+DATA_V2
AND X,X,$FF
AND Y,Y,$FF
MUL X,X,Y
LD Y,A+V_RES
AND Y,Y,$FFFF
SUB 0,X,Y
JNZ 0+ERR_VALU
LD X,A+DATA_V ;low word
LD Y,A+DATA_V2
ST 0+AKKU,A
OR A,0,0
VMUL_LOOP_B2: LSR X,X
LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VMUL_LOOP_B2
AND X,X,$FF
AND Y,Y,$FF
MUL X,X,Y
LD A,0+AKKU
LD Y,A+V_RES
OR A,0,0
VMUL_LOOP_B3: LSR Y,Y
INC A,A
SUB 0,A,16
JNZ 0+VMUL_LOOP_B3
SUB 0,X,Y
JNZ 0+ERR_VALU
LD A,0+AKKU
INC A,A
SUB 0,A,k
JNZ 0+VMUL_LOOP_B
NO_VMUL: NOP
TEST_VMOLR: OR A,0,use_mul
JZ 0+NO_VMOLR
OR A,0,DATA_V
VLD R0,0+A
OR A,0,DATA_V2
VLD R1,0+A
VMOL R2,R0
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VMOL_LOOP: LD X,A+V_RES
LD Y,A+DATA_V2
SUB 0,X,Y
JNZ 0+ERR_VMOLR
SUB 0,A,k
JNZ 0+VMOL_LOOP
VMOR R2,R1
OR A,0,V_RES
VST 0+A,R2
OR A,0,0
VMOR_LOOP: LD X,A+V_RES
LD Y,A+DATA_V
SUB 0,X,Y
JNZ 0+ERR_VMOLR
SUB 0,A,k
JNZ 0+VMOR_LOOP
NO_VMOLR: NOP
FINISH: JMP 0+FINISH
ERR_SCALAR: HALT
ERR_COOP: HALT
ERR_VECTOR: HALT
ERR_VALU: HALT
ERR_SIMUL: HALT
ERR_VSHUF: HALT
ERR_VMOLR: HALT
 
AKKU: DC 0
CARRY: DC 0
X_REG: DC 0
Y_REG: DC 0
I: DC 0
 
A_REG: DC 0
B_REG: DC 0
RES_REG: DC 0
/branches/avendor/assembler/clvpasm.py
0,0 → 1,807
from pyparsing import *
 
#------------------------------------------------------------------------------------------------------
# CLASS ASSEMBLER
#------------------------------------------------------------------------------------------------------
class Assembler(object):
def __init__(self, args):
formaterList = FormaterList()
formaterList.registerComponent("bin", Binary_Formater)
formaterList.registerComponent("vhdl", VHDL_Formater)
formaterList.registerComponent("coe", COE_Formater)
formaterList.registerComponent("symboltable", SYMBOLTABLE_Formater)
if len(args) != 4:
print
print "usage: python clvpasm.py <format> <infilename> <outfilename>"
print " supported formats are: " + formaterList.getList()
sys.exit(1)
format = args[1]
fileNameIn = args[2]
fileNameOut = args[3]
formater = formaterList.getFormater(format)
if formater == None:
print
print "error: unsupported format, use one of the following: " + formaterList.getList()
sys.exit(1)
try:
fileIn = open (fileNameIn,"r")
programcode, symbols = Parser().parse(fileIn.readlines())
fileIn.close()
except IOError:
print
print "error: unable to open input file: " + fileNameIn
sys.exit(1)
try:
formaterList.getFormater(format).write(programcode, symbols, fileNameOut)
print "done"
except IOError:
print
print "error: unable to write output file: " + fileNameOut
sys.exit(1)
#------------------------------------------------------------------------------------------------------
# CLASS FORMATERLIST
#------------------------------------------------------------------------------------------------------
class FormaterList(object):
def __init__(self):
self.components = []
def getFormater(self, format):
for a in self.components:
if format.lower().lstrip().startswith(a[0].lower()):
return a[1]()
return None;
def getList(self):
cmdlist = []
for a in self.components:
cmdlist.append(a[0])
return str(cmdlist)
def registerComponent(self,format,component):
self.components.append([format,component])
 
#------------------------------------------------------------------------------------------------------
# CLASS VHDL_FORMATER
#------------------------------------------------------------------------------------------------------
class VHDL_Formater(object):
def write(self, code, symbols, filename):
#get last adress
list = sorted(code.iteritems())
list.reverse()
end = list[0][0]
f=open(filename,"w")
f.write("-- *****************************************\n")
f.write("-- * SRAM FILE GENERATED BY CLVP ASSEMBLER *\n")
f.write("-- * do not make modifications here *\n")
f.write("-- *****************************************\n\n")
f.write("library ieee;\nuse ieee.std_logic_1164.all;\nuse ieee.std_logic_unsigned.all;\n")
f.write("entity sram is\n\tport (\n\t\tclk : in std_logic;\n\t\twe : in std_logic;\n\t\ten : in std_logic;\n")
f.write("\t\taddr : in std_logic_vector(31 downto 0);\n\t\tdi : in std_logic_vector(31 downto 0);\n")
f.write("\t\tdo : out std_logic_vector(31 downto 0)\n\t);\nend sram;\n")
f.write("architecture rtl of sram is\n")
f.write("\ttype memory_type is array(0 to " + str(end+1) + ") of std_logic_vector(31 downto 0);\n")
f.write("\tsignal memory : memory_type := (\n")
for i in range(0,end+1):
if code.has_key(i):
f.write('\t\t"' + code[i][0] + '", -- ' + hex(i) + ' : ' +code[i][1] +'\n')
else:
f.write('\t\t"00000000000000000000000000000000", -- ' + hex(i)+'\n')
f.write('\t\t"00000000000000000000000000000000"'+'\n')
f.write('\t);'+'\n')
f.write("begin\n\tprocess (clk)\n\tbegin\n\t\tif clk'event and clk = '1' then\n\t\t\tif en = '1' then\n")
f.write("\t\t\t\tif we = '1' then\n\t\t\t\t\tmemory(conv_integer(addr)) <= di;\n\t\t\t\t\tdo <= di;\n")
f.write("\t\t\t\telse\n\t\t\t\t\tdo <= memory(conv_integer(addr));\n\t\t\t\tend if;\n\t\t\tend if;\n\t\tend if;\n")
f.write("\tend process;\nend;\n")
 
f.close()
#------------------------------------------------------------------------------------------------------
# CLASS BINARY_FORMATER
#------------------------------------------------------------------------------------------------------
class Binary_Formater(object):
def write(self, code, symbols, filename):
#get last adress
list = sorted(code.iteritems())
list.reverse()
end = list[0][0]
f=open(filename,"wb")
for i in range(0,end+1):
if code.has_key(i):
value = string.atoi(code[i][0],2)
m = string.atoi("11111111000000000000000000000000",2)
for j in range(4):
a = (value & m) >> 8 * (3-j)
m = m >> 8
f.write(chr(a))
else:
f.write(chr(0) + chr(0) + chr(0) + chr(0))
f.close()
#------------------------------------------------------------------------------------------------------
# CLASS COE_FORMATER
#------------------------------------------------------------------------------------------------------
class COE_Formater(object):
def write(self, code, symbols, filename):
#get last adress
list = sorted(code.iteritems())
list.reverse()
end = list[0][0]
f=open(filename,"w")
f.write("; COE FILE FOR XILINX CORE GENERATOR\n")
f.write("; depth=" + str(end + 1) + ", and width=32\n")
f.write(";\n")
f.write("memory_initialization_radix=2;\n")
f.write("memory_initialization_vector=\n")
for i in range(0,end+1):
if code.has_key(i):
f.write(code[i][0] + ",\n")
else:
f.write("00000000000000000000000000000000,\n")
f.write("00000000000000000000000000000000;\n")
f.close()
#------------------------------------------------------------------------------------------------------
# CLASS SYMBOLTABLE_FORMATER
#------------------------------------------------------------------------------------------------------
class SYMBOLTABLE_Formater(object):
def write(self, code, symbols, filename):
f=open(filename,"w")
for sym, addr in sorted(symbols.iteritems()):
f.write(str(addr) + ":" + str(sym) + "\n")
f.close()
 
 
#------------------------------------------------------------------------------------------------------
# CLASS INSTRUCTION
#------------------------------------------------------------------------------------------------------
class Instruction(object):
def __init__(self):
self.bincode = []
for i in range(32):
self.bincode.append("0")
def revert(self,value):
result = ""
for i in range(len(value),0,-1):
result = result + value[i-1]
return result
def insert(self, start, end, value):
for i in range (start+1, end, -1):
self.bincode[i-1] = self.revert(value)[i-1-end]
def tostring(self):
result = ""
for i in range(32,0, -1):
result = result + self.bincode[i-1]
return result
def tobinary(self,n):
b = ""
if n == 0:
b= "0"
else:
while n > 0:
b = str(n % 2) + b
n = n >> 1
return b
def insertImmediate(self, n):
self.insert(15,0,self.tobinary(n).rjust(16,"0"))
def insertConstant(self, n):
self.insert(31,0,self.tobinary(n).rjust(32,"0"))
def insertR(self,r):
self.insert(11,8,self.tobinary(r).rjust(4,"0"))
def insertV(self,v):
self.insert(7,4,self.tobinary(v).rjust(4,"0"))
def insertW(self,w):
self.insert(3,0,self.tobinary(w).rjust(4,"0"))
def insertVectorImmediate(self,n):
self.insert(27,20,self.tobinary(n).rjust(8,"0"))
#------------------------------------------------------------------------------------------------------
# CLASS PARSER
#------------------------------------------------------------------------------------------------------
class Parser:
def tointeger(self,s):
if s[0] == "$":
return string.atoi(s[1:], base = 16)
if s[0] == "%":
return string.atoi(s[1:], base = 2)
if s[0] == "R":
return string.atoi(s[1:])
return string.atoi(s)
def parse(self, program):
#create parsed commandlist
errorcounter = 0
commands = []
linenr = 0
for line in program:
linenr = linenr + 1
line = line.strip().upper()
try:
result = LineParser().parseLine(line)
if result.dcommand or result.vcommand or result.command or result.ccommand:
commands.append((result, linenr))
except ParseException, err:
print
print "conflict in line " + str(linenr) + ":"
print line
print " "*err.loc + "^ " + "parse error"
errorcounter = errorcounter + 1
#create symbol table, assign adresses, detect conflicts
symbols = {}
program = {}
address = 0
for cmd, linenr in commands:
if cmd.dcommand == "ORG":
address = self.tointeger(cmd.address)
if cmd.dcommand == "EQU":
if symbols.has_key(cmd.symbol):
print
print "conflict in line " + str(linenr) + ":"
print "=> symbol " + cmd.symbol + " has already been defined"
errorcounter = errorcounter + 1
else:
symbols[cmd.symbol] = self.tointeger(cmd.value)
if cmd.label:
if symbols.has_key(cmd.label[0]):
print
print "conflict in line " + str(linenr) + ":"
print "=> symbol " + cmd.label[0] + " has already been defined"
errorcounter = errorcounter + 1
else:
symbols[cmd.label[0]] = address
if cmd.dcommand != "ORG" and cmd.dcommand != "EQU":
if program.has_key(address):
print
print "conflict in line " + str(linenr) + ":"
print "=> memory address " + hex(address) + " is already in use"
errorcounter = errorcounter + 1
 
program [address] = (cmd, linenr)
address = address + 1
#translate into machine program
code = {}
for addr, prg in sorted(program.iteritems()):
cmd = prg[0]
linenr = prg[1]
 
if cmd.command and cmd.vcommand and cmd.immediate:
print
print "conflict in line " + str(linenr) + ":"
print "=> you can't combine " + cmd.command + " (with immediate value) and " + cmd.vcommand
errorcounter = errorcounter + 1
immediate = 0
 
if cmd.immediate:
try:
if cmd.value:
immediate = self.tointeger(cmd.value)
else:
immediate = symbols[cmd.symbol]
except KeyError:
print
print "conflict in line " + str(linenr) + ":"
print "=> symbol " + cmd.symbol + " not declared"
errorcounter = errorcounter + 1
if immediate > 65535:
print
print "conflict in line " + str(linenr) + ":"
print "=> immediate value " + cmd.immediate +" (" + hex(immediate) + ") is out of range (max = 0xFFFF)"
errorcounter = errorcounter + 1
if cmd.rvector_register:
if self.tointeger(cmd.rvector_register) > Settings().getN()-1:
print
print "conflict in line " + str(linenr) + ":"
print "=> vector register (" + cmd.rvector_register + ") is out of range (R0..R"+ str(Settings().getN()-1) + ")"
errorcounter = errorcounter + 1
if cmd.vvector_register:
if self.tointeger(cmd.vvector_register) > Settings().getN()-1:
print
print "conflict in line " + str(linenr) + ":"
print "=> vector register (" + cmd.vvector_register + ") is out of range (R0..R"+ str(Settings().getN()-1) + ")"
errorcounter = errorcounter + 1
if cmd.wvector_register:
if self.tointeger(cmd.wvector_register) > Settings().getN()-1:
print
print "conflict in line " + str(linenr) + ":"
print "=> vector register (" + cmd.wvector_register + ") is out of range (R0..R"+ str(Settings().getN()-1) + ")"
errorcounter = errorcounter + 1
i = Instruction()
register = {"0":"00","A":"01","X":"10","Y":"11"}
wordlength = {"B":"00","W":"01","DW":"10","QW":"11"}
alucommand = False
jumpcommand = False
valucommand = False
immediate_possible = True
#directive commands
if cmd.dcommand == "DC":
i.insertConstant(self.tointeger(cmd.address))
#scalar commands
if cmd.command == "ADD":
alucommand = True
i.insert(29,26,"0000")
if cmd.command == "ADC":
alucommand = True
i.insert(29,26,"0001")
if cmd.command == "SUB":
alucommand = True
i.insert(29,26,"0010")
if cmd.command == "SBC":
alucommand = True
i.insert(29,26,"0011")
if cmd.command == "AND":
alucommand = True
i.insert(29,26,"1000")
if cmd.command == "OR":
alucommand = True
i.insert(29,26,"1001")
if cmd.command == "XOR":
alucommand = True
i.insert(29,26,"1010")
if cmd.command == "MUL":
alucommand = True
i.insert(29,26,"1011")
if cmd.command == "INC":
alucommand = True
i.insert(29,26,"0100")
if cmd.command == "DEC":
alucommand = True
i.insert(29,26,"0110")
 
if cmd.command == "LSL":
alucommand = True
i.insert(29,26,"1100")
if cmd.command == "LSR":
alucommand = True
i.insert(29,26,"1110")
if cmd.command == "ROL":
alucommand = True
i.insert(29,26,"1101")
if cmd.command == "ROR":
alucommand = True
i.insert(29,26,"1111")
if cmd.command == "LD":
i.insert(31,28,"1000")
i.insert(25,24,register[cmd.dregister])
i.insert(23,22,register[cmd.sregister])
immediate_possible = True
if cmd.command == "ST":
i.insert(31,28,"1010")
i.insert(23,22,register[cmd.sregister])
immediate_possible = True
if cmd.command == "HALT":
i.insert(31,27,"00101")
if cmd.command == "NOP":
i.insert(31,29,"000")
if cmd.command == "JMP":
i.insert(31,24,"00100000")
jumpcommand = True
if cmd.command == "JAL":
i.insert(31,26,"001000")
i.insert(25,24,register[cmd.dregister])
jumpcommand = True
if cmd.command == "JNC":
i.insert(31,24,"00110000")
jumpcommand = True
if cmd.command == "JC":
i.insert(31,24,"00110100")
jumpcommand = True
if cmd.command == "JNZ":
i.insert(31,24,"00111000")
jumpcommand = True
if cmd.command == "JZ":
i.insert(31,24,"00111100")
jumpcommand = True
 
if cmd.command == "CLC":
i.insert(31,26,"110000")
i.insert(23,20,"0100")
if cmd.command == "CLZ":
i.insert(31,26,"110000")
i.insert(23,20,"1000")
if cmd.command == "SEC":
i.insert(31,26,"110000")
i.insert(23,20,"0101")
if cmd.command == "SEZ":
i.insert(31,26,"110000")
i.insert(23,20,"1010")
#common parts of scalar commands
if alucommand == True:
i.insert(31,30,"01");
i.insert(25,24,register[cmd.dregister])
i.insert(23,22,register[cmd.sregister])
immediate_possible = True
if jumpcommand == True:
i.insert(23,22,register[cmd.sregister])
immediate_possible = True
if immediate_possible == True:
if(cmd.immediate):
i.insert(21,20,"00")
i.insert(19,17,"000")
i.insertImmediate(immediate)
else:
if cmd.tregister:
i.insert(21,20,register[cmd.tregister])
#vector commands
if cmd.vcommand == "VADD":
i.insert(15,12,"0000")
valucommand = True
if cmd.vcommand == "VSUB":
i.insert(15,12,"0010")
valucommand = True
if cmd.vcommand == "VAND":
i.insert(15,12,"1000")
valucommand = True
if cmd.vcommand == "VOR":
i.insert(15,12,"1001")
valucommand = True
if cmd.vcommand == "VMUL":
i.insert(15,12,"1011")
valucommand = True
if cmd.vcommand == "VXOR":
i.insert(15,12,"1010")
valucommand = True
if cmd.vcommand == "VLSL":
i.insert(15,12,"1100")
valucommand = True
if cmd.vcommand == "VLSR":
i.insert(15,12,"1110")
valucommand = True
if cmd.vcommand == "VNOP":
i.insert(19,17,"000")
if cmd.vcommand == "VMOL":
i.insert(19,17,"001")
i.insert(15,12,"1000")
i.insertR(self.tointeger(cmd.rvector_register))
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.vcommand == "VMOR":
i.insert(19,17,"001")
i.insert(15,12,"1100")
i.insertR(self.tointeger(cmd.rvector_register))
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.vcommand == "VMOV":
i.insert(19,17,"001")
if cmd.rvector_register and cmd.vvector_register: #vmov r,v
i.insert(15,12,"0001")
i.insertR(self.tointeger(cmd.rvector_register))
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.immediate:
if immediate > 255:
print
print "conflict in line " + str(linenr) + ":"
print "=> immediate value " + cmd.immediate +" (" + hex(immediate) + ") is out of range (max = 0xFF)"
errorcounter = errorcounter + 1
else:
if cmd.rvector_register: #vmov r, r<n>
i.insertVectorImmediate(immediate)
i.insert(15,12,"0010")
i.insertR(self.tointeger(cmd.rvector_register))
if cmd.vvector_register: #vmov r<n>,r
i.insertVectorImmediate(immediate)
i.insert(15,12,"0011")
i.insertV(self.tointeger(cmd.vvector_register))
#common parts of vector commands
if valucommand == True:
i.insert(19,18,"01")
i.insert(17,16,wordlength[cmd.width])
i.insertR(self.tointeger(cmd.rvector_register))
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.wvector_register:
i.insertW(self.tointeger(cmd.wvector_register))
#cooperative commands
if cmd.ccommand == "VLD":
i.insert(31,28,"1001")
i.insert(23,22,register[cmd.sregister])
i.insert(21,20,register[cmd.tregister])
i.insert(19,18,"10")
i.insert(15,12,"0010")
i.insertR(self.tointeger(cmd.rvector_register))
if cmd.ccommand == "VST":
i.insert(31,26,"101100")
i.insert(23,22,register[cmd.sregister])
i.insert(21,20,register[cmd.tregister])
i.insert(19,18,"10")
i.insert(15,12,"0011")
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.ccommand == "MOV":
if cmd.rvector_register and cmd.tregister and cmd.sregister: #mov r(t),s
i.insert(31,26,"101110")
i.insert(23,22,register[cmd.sregister])
i.insert(21,20,register[cmd.tregister])
i.insert(19,18,"10")
i.insert(15,12,"0100")
i.insertR(self.tointeger(cmd.rvector_register))
if cmd.vvector_register and cmd.tregister and cmd.dregister: #mov d,v(t)
i.insert(31,26,"101111")
i.insert(25,24,register[cmd.dregister])
i.insert(21,20,register[cmd.tregister])
i.insert(19,18,"10")
i.insert(15,12,"0101")
i.insertV(self.tointeger(cmd.vvector_register))
if cmd.ccommand == "MOVA":
i.insert(31,26,"101101")
i.insert(23,22,register[cmd.sregister])
i.insert(19,18,"10")
i.insert(15,12,"0110")
i.insertR(self.tointeger(cmd.rvector_register))
if cmd.ccommand == "VSHUF":
i.insert(31,29,"000")
i.insert(19,18,"11")
i.insert(17,16,cmd.perm[0:2])
i.insert(15,12,cmd.perm[2:6])
i.insert(27,20,cmd.perm[6:14])
i.insertR(self.tointeger(cmd.rvector_register))
i.insertV(self.tointeger(cmd.vvector_register))
i.insertW(self.tointeger(cmd.wvector_register))
code [addr] = (i.tostring(), string.join(cmd))
 
if errorcounter > 0:
print
print str(errorcounter) + " error(s) found => output has not been written"
sys.exit(1)
else:
return code, symbols
 
#------------------------------------------------------------------------------------------------------
# CLASS LINEPARSER
#------------------------------------------------------------------------------------------------------
class LineParser:
def parseLine(self,line):
expression = Forward()
dec_value = Word("0123456789", min=1)
hex_value = Word("$","ABCDEF0123456789", min=2)
bin_value = Word("%","10", min=2)
value = (dec_value ^ hex_value ^ bin_value).setResultsName("value")
ident = Word( alphas, alphanums + "_" ).setResultsName("symbol")
immediate = (value ^ ident).setResultsName("immediate")
perm = Word("10", min=14, max=14).setResultsName("perm")
length = (Literal("B") ^ Literal("W") ^ Literal("DW") ^ Literal("QW")).setResultsName("width")
mult_length = (Literal("B") ^ Literal("W")).setResultsName("width")
width = ("." + length)
mult_width = ("." + mult_length)
label = (ident + ":").setResultsName("label")
comment = ( ";" + restOfLine).setResultsName("comment")
dregister = (Literal("A") ^ Literal("X") ^ Literal("Y") ^ Literal("0")).setResultsName("dregister")
sregister = (Literal("A") ^ Literal("X") ^ Literal("Y") ^ Literal("0")).setResultsName("sregister")
tregister = (Literal("A") ^ Literal("X") ^ Literal("Y")).setResultsName("tregister")
akku = Literal("A")
rvector_register = Word("R","0123456789",min=2).setResultsName("rvector_register")
vvector_register = Word("R","0123456789",min=2).setResultsName("vvector_register")
wvector_register = Word("R","0123456789",min=2).setResultsName("wvector_register")
directive_cmd_keyword_1 = (Keyword("ORG") ^ Keyword("DC")).setResultsName("dcommand")
directive_cmd_keyword_2 = (Keyword("EQU")).setResultsName("dcommand")
directive_cmd_1 = directive_cmd_keyword_1 + value.setResultsName("address")
directive_cmd_2 = directive_cmd_keyword_2 + ident + value
directive_cmd = (directive_cmd_1 ^ directive_cmd_2)
alu_cmd_keyword_1 = (Keyword("INC") ^ Keyword("DEC") ^ Keyword("LSL") ^ Keyword("LSR") ^ Keyword("ROL") \
^ Keyword("ROR")).setResultsName("command")
alu_cmd_keyword_2 = (Keyword("ADD") ^ Keyword("ADC") ^ Keyword("SUB") ^ Keyword("SBC") ^ Keyword("AND") \
^ Keyword("OR") ^ Keyword("XOR") ^ Keyword("MUL")).setResultsName("command")
alu_cmd_1 = alu_cmd_keyword_1 + dregister + "," + sregister
alu_cmd_2 = alu_cmd_keyword_2 + dregister + "," + sregister + "," + (tregister ^ immediate)
alu_cmd = (alu_cmd_1 ^ alu_cmd_2)
jmp_cmd_keyword_1 = (Keyword("JMP") ^ Keyword("JNC") ^ Keyword("JC") ^ Keyword("JNZ") ^ Keyword("JZ")) \
.setResultsName("command")
jmp_cmd_keyword_2 = Keyword("JAL").setResultsName("command")
jmp_cmd_1 = jmp_cmd_keyword_1 + Optional("[") + sregister + "+" + (tregister ^ immediate) + Optional("]")
jmp_cmd_2 = jmp_cmd_keyword_2 + dregister + "," + Optional("[") + sregister + "+" + (tregister ^ immediate) + Optional("]")
jmp_cmd = (jmp_cmd_1 ^ jmp_cmd_2)
inherent_cmd_keyword = (Keyword ("HALT") ^ Keyword ("NOP") ^ Keyword ("CLC") ^ Keyword ("CLZ") ^ Keyword ("SEC") \
^ Keyword ("SEZ")).setResultsName("command")
inherent_cmd = inherent_cmd_keyword
load_cmd_keyword = Keyword("LD").setResultsName("command")
load_cmd = load_cmd_keyword + dregister + "," + Optional("[") + sregister + "+" + (tregister ^ immediate) + Optional("]")
store_cmd_keyword = Keyword("ST").setResultsName("command")
store_cmd = store_cmd_keyword + Optional("[") + sregister + "+" + (tregister ^ immediate) + Optional("]") +"," + akku
scalar_command = (alu_cmd ^ jmp_cmd ^ inherent_cmd ^ load_cmd ^ store_cmd)
mov_cmd_keyword = Keyword("MOV").setResultsName("ccommand")
mov_cmd_1 = mov_cmd_keyword + rvector_register + "(" + tregister + ")" + "," + sregister
mov_cmd_2 = mov_cmd_keyword + dregister + "," + vvector_register + "(" + tregister + ")"
mov_cmd = (mov_cmd_1 ^ mov_cmd_2)
vld_cmd_keyword = Keyword("VLD").setResultsName("ccommand")
vld_cmd = vld_cmd_keyword + rvector_register + "," + Optional("[") + sregister + "+" + tregister + Optional("]")
vst_cmd_keyword = Keyword("VST").setResultsName("ccommand")
vst_cmd = vst_cmd_keyword + Optional("[") + sregister + "+" + tregister + Optional("]") + "," + vvector_register
shuffle_cmd_keyword = Keyword("VSHUF").setResultsName("ccommand")
shuffle_cmd = shuffle_cmd_keyword + rvector_register + "," + vvector_register + "," + wvector_register + "," + perm
mova_cmd_keyword = Keyword("MOVA").setResultsName("ccommand")
mova_cmd = mova_cmd_keyword + rvector_register + "," + sregister
coop_command = (mov_cmd ^ vld_cmd ^ vst_cmd ^ shuffle_cmd ^ mova_cmd)
valu_cmd_keyword_1 = (Keyword("VADD") ^ Keyword("VSUB") ^ Keyword("VAND") ^ Keyword("VOR") ^ Keyword("VXOR")) \
.setResultsName("vcommand")
valu_cmd_keyword_2 = (Keyword("VLSL") ^ Keyword("VLSR")).setResultsName("vcommand")
valu_cmd_keyword_3 = Keyword("VMUL").setResultsName("vcommand")
valu_cmd_1 = valu_cmd_keyword_1 + width + rvector_register + "," + vvector_register + "," + wvector_register
valu_cmd_2 = valu_cmd_keyword_2 + width + rvector_register + "," + vvector_register
valu_cmd_3 = valu_cmd_keyword_3 + mult_width + rvector_register + "," + vvector_register + "," + wvector_register
valu_cmd = (valu_cmd_1 ^ valu_cmd_2 ^ valu_cmd_3)
vnop_cmd_keyword = Keyword("VNOP").setResultsName("vcommand")
vnop_cmd = vnop_cmd_keyword
vmov_cmd_keyword = Keyword("VMOV").setResultsName("vcommand")
vmov_cmd_1 = vmov_cmd_keyword + rvector_register + "," + vvector_register
vmov_cmd_2 = vmov_cmd_keyword + rvector_register + "," + "R" + "<" + immediate + ">"
vmov_cmd_3 = vmov_cmd_keyword + "R" + "<" + immediate + ">" + "," + vvector_register
vmov_cmd = (vmov_cmd_1 ^ vmov_cmd_2 ^ vmov_cmd_3)
vmolr_cmd_keyword = (Keyword("VMOL") ^ Keyword("VMOR")).setResultsName("vcommand")
vmolr_cmd = vmolr_cmd_keyword + rvector_register + "," + vvector_register
vector_command = (valu_cmd ^ vnop_cmd ^ vmov_cmd ^ vmolr_cmd)
command = ((directive_cmd ^ scalar_command ^ coop_command ^ vector_command) \
^ (scalar_command + "|" + vector_command )\
^ (vector_command + "|" + scalar_command ))
expression << (Optional((Optional(label) + command)) + Optional(comment) + lineEnd)
result = expression.parseString(line)
return result
 
#------------------------------------------------------------------------------------------------------
# CLASS SETTINGS
#------------------------------------------------------------------------------------------------------
class Settings(object):
def getN(self):
return 16
def getK(self):
return 16
 
#------------------------------------------------------------------------------------------------------
# MAIN PROGRAM
#------------------------------------------------------------------------------------------------------
if __name__ == '__main__':
Assembler(sys.argv)
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.