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

Subversion Repositories wb_lcd

[/] [wb_lcd/] [trunk/] [myhdl/] [wb_lcd_workspace_ramless/] [workspace/] [.metadata/] [.plugins/] [org.eclipse.core.resources/] [.history/] [e4/] [c0d042651e2d001e1d938226a9f3d8bc] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jvillar
#  This file is part of the myhdl library, a Python package for using
2
#  Python as a Hardware Description Language.
3
#
4
#  Copyright (C) 2003-2008 Jan Decaluwe
5
#
6
#  The myhdl library is free software; you can redistribute it and/or
7
#  modify it under the terms of the GNU Lesser General Public License as
8
#  published by the Free Software Foundation; either version 2.1 of the
9
#  License, or (at your option) any later version.
10
#
11
#  This library is distributed in the hope that it will be useful, but
12
#  WITHOUT ANY WARRANTY; without even the implied warranty of
13
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
#  Lesser General Public License for more details.
15
#
16
#  You should have received a copy of the GNU Lesser General Public
17
#  License along with this library; if not, write to the Free Software
18
#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
 
20
""" myhdl toVerilog analysis module.
21
 
22
"""
23
 
24
 
25
import inspect
26
import compiler
27
from compiler import ast as astNode
28
from sets import Set
29
from types import GeneratorType, FunctionType, ClassType, MethodType
30
from cStringIO import StringIO
31
import re
32
import warnings
33
import __builtin__
34
 
35
import myhdl
36
from myhdl import *
37
from myhdl import ConversionError
38
from myhdl._unparse import _unparse
39
from myhdl._cell_deref import _cell_deref
40
from myhdl._always_comb import _AlwaysComb
41
from myhdl._always import _Always
42
from myhdl._delay import delay
43
from myhdl.conversion._misc import (_error, _access, _kind, _context,
44
                                    _ConversionMixin, _Label, _genUniqueSuffix)
45
from myhdl._extractHierarchy import _isMem, _UserCode
46
from myhdl._Signal import _WaiterList
47
from myhdl._util import _isTupleOfInts
48
 
49
myhdlObjects = myhdl.__dict__.values()
50
builtinObjects = __builtin__.__dict__.values()
51
 
52
_enumTypeSet = set()
53
 
54
 
55
def _makeName(n, prefixes):
56
    if len(prefixes) > 1:
57
#        name = '_' + '_'.join(prefixes[1:]) + '_' + n
58
        name = '_'.join(prefixes[1:]) + '_' + n
59
    else:
60
        name = n
61
    if '[' in name or ']' in name:
62
        name = "\\" + name + ' '
63
##     print prefixes
64
##     print name
65
    return name
66
 
67
def _analyzeSigs(hierarchy, hdl='Verilog'):
68
    curlevel = 0
69
    siglist = []
70
    memlist = []
71
    prefixes = []
72
    open, close = '[', ']'
73
    if hdl == 'VHDL':
74
        open, close = '(', ')'
75
 
76
    for inst in hierarchy:
77
        level = inst.level
78
        name = inst.name
79
        sigdict = inst.sigdict
80
        memdict = inst.memdict
81
        delta = curlevel - level
82
        curlevel = level
83
        assert(delta >= -1)
84
        if delta == -1:
85
            prefixes.append(name)
86
        else:
87
            prefixes = prefixes[:curlevel-1]
88
            prefixes.append(name)
89
        assert prefixes[-1] == name
90
        for n, s in sigdict.items():
91
            if s._name is not None:
92
                continue
93
            s._name = _makeName(n, prefixes)
94
            if not s._nrbits:
95
                raise ConversionError(_error.UndefinedBitWidth, s._name)
96
            siglist.append(s)
97
        # list of signals
98
        for n, m in memdict.items():
99
            if m.name is not None:
100
                continue
101
            m.name = _makeName(n, prefixes)
102
            memlist.append(m)
103
 
104
    # handle the case where a named signal appears in a list also by giving
105
    # priority to the list and marking the signals as unused
106
    for m in memlist:
107
        if not m._used:
108
            continue
109
        m._driven = 'reg'
110
        for i, s in enumerate(m.mem):
111
            s._name = "%s%s%s%s" % (m.name, open, i, close)
112
            s._used = False
113
            if s._inList:
114
                raise ConversionError(_error.SignalInMultipleLists, s._name)
115
            s._inList = True
116
            if not s._nrbits:
117
                raise ConversionError(_error.UndefinedBitWidth, s._name)
118
            if type(s.val) != type(m.elObj.val):
119
                raise ConversionError(_error.InconsistentType, s._name)
120
            if s._nrbits != m.elObj._nrbits:
121
                raise ConversionError(_error.InconsistentBitWidth, s._name)
122
 
123
    return siglist, memlist
124
 
125
 
126
 
127
def _analyzeGens(top, absnames):
128
    genlist = []
129
    for g in top:
130
        if isinstance(g, _UserCode):
131
            ast = g
132
        elif isinstance(g, (_AlwaysComb, _Always)):
133
            f = g.func
134
            s = inspect.getsource(f)
135
            # remove decorators
136
            s = re.sub(r"@.*", "", s)
137
            s = s.lstrip()
138
            ast = compiler.parse(s)
139
            # print ast
140
            ast.sourcefile = inspect.getsourcefile(f)
141
            ast.lineoffset = inspect.getsourcelines(f)[1]-1
142
            ast.symdict = f.func_globals.copy()
143
            ast.callstack = []
144
            # handle free variables
145
            if f.func_code.co_freevars:
146
                for n, c in zip(f.func_code.co_freevars, f.func_closure):
147
                    obj = _cell_deref(c)
148
                    if isinstance(g, _AlwaysComb):
149
                        print type(obj)
150
                        assert isinstance(obj, (int, long, Signal)) or \
151
                               _isMem(obj) or _isTupleOfInts(obj)
152
                    ast.symdict[n] = obj
153
            ast.name = absnames.get(id(g), str(_Label("BLOCK"))).upper()
154
            v = _NotSupportedVisitor(ast)
155
            compiler.walk(ast, v)
156
            if isinstance(g, _AlwaysComb):
157
                v = _AnalyzeAlwaysCombVisitor(ast, g.senslist)
158
            else:
159
                v = _AnalyzeAlwaysDecoVisitor(ast, g.senslist)
160
            compiler.walk(ast, v)
161
        else: # @instance
162
            f = g.gen.gi_frame
163
            s = inspect.getsource(f)
164
            # remove decorators
165
            s = re.sub(r"@.*", "", s)
166
            s = s.lstrip()
167
            ast = compiler.parse(s)
168
            # print ast
169
            ast.sourcefile = inspect.getsourcefile(f)
170
            ast.lineoffset = inspect.getsourcelines(f)[1]-1
171
            ast.symdict = f.f_globals.copy()
172
            ast.symdict.update(f.f_locals)
173
            ast.callstack = []
174
            ast.name = absnames.get(id(g), str(_Label("BLOCK"))).upper()
175
            v = _NotSupportedVisitor(ast)
176
            compiler.walk(ast, v)
177
            v = _AnalyzeBlockVisitor(ast)
178
            compiler.walk(ast, v)
179
        genlist.append(ast)
180
    return genlist
181
 
182
 
183
class _NotSupportedVisitor(_ConversionMixin):
184
 
185
    def __init__(self, ast):
186
        self.ast = ast
187
        self.toplevel = True
188
 
189
    def visitAssList(self, node, *args):
190
        self.raiseError(node, _error.NotSupported, "list assignment")
191
    def visitAssTuple(self, node, *args):
192
        self.raiseError(node, _error.NotSupported, "tuple assignment")
193
    def visitBackquote(self, node, *args):
194
        self.raiseError(node, _error.NotSupported, "backquote")
195
    def visitClass(self, node, *args):
196
        self.raiseError(node, _error.NotSupported, "class statement")
197
    def visitDict(self, node, *args):
198
        self.raiseError(node, _error.NotSupported, "dictionary")
199
    def visitDiv(self, node, *args):
200
        self.raiseError(node, _error.NotSupported, "true division - consider '//'")
201
    def visitEllipsis(self, node, *args):
202
        self.raiseError(node, _error.NotSupported, "ellipsis")
203
    def visitExec(self, node, *args):
204
        self.raiseError(node, _error.NotSupported, "exec statement")
205
    def visitExpression(self, node, *args):
206
        self.raiseError(node, _error.NotSupported, "Expression node")
207
    def visitFrom(self, node, *args):
208
        self.raiseError(node, _error.NotSupported, "from statement")
209
    def visitGlobal(self, node, *args):
210
        self.raiseError(node, _error.NotSupported, "global statement")
211
    def visitImport(self, node, *args):
212
        self.raiseError(node, _error.NotSupported, "import statement")
213
    def visitLambda(self, node, *args):
214
        self.raiseError(node, _error.NotSupported, "lambda statement")
215
    def visitListComp(self, node, *args):
216
        if len(node.quals) > 1:
217
            self.raiseError(node, _error.NotSupported, "multiple for statements in list comprehension")
218
        self.visitChildNodes(node)
219
    def visitListCompIf(self, node, *args):
220
        self.raiseError(node, _error.NotSupported, "if statement in list comprehension")
221
    def visitList(self, node, *args):
222
        self.raiseError(node, _error.NotSupported, "list")
223
    def visitSliceObj(self, node):
224
        self.raiseError(node, _error.NotSupported, "slice object")
225
    def visitTryExcept(self, node, *args):
226
        self.raiseError(node, _error.NotSupported, "try-except statement")
227
    def visitTryFinally(self, node, *args):
228
        self.raiseError(node, _error.NotSupported, "try-finally statement")
229
 
230
    def visitAnd(self, node):
231
        self.visitChildNodes(node)
232
 
233
    def visitOr(self, node):
234
        self.visitChildNodes(node)
235
 
236
    def visitAssign(self, node, *args):
237
        if len(node.nodes) > 1:
238
            self.raiseError(node, _error.NotSupported, "multiple assignments")
239
        self.visit(node.nodes[0], *args)
240
        self.visit(node.expr, *args)
241
 
242
    def visitCallFunc(self, node):
243
        if node.star_args:
244
            self.raiseError(node, _error.NotSupported, "extra positional arguments")
245
        if node.dstar_args:
246
            self.raiseError(node, _error.NotSupported, "extra named arguments")
247
        # f = eval(_unparse(node.node), self.ast.symdict)
248
        self.visitChildNodes(node)
249
 
250
    def visitCompare(self, node, *args):
251
        if len(node.ops) != 1:
252
            self.raiseError(node, _error.NotSupported, "chained comparison")
253
        self.visitChildNodes(node, *args)
254
 
255
    def visitFunction(self, node, *args):
256
        if node.flags != 0: # check flags
257
            self.raiseError(node, _error.NotSupported, "extra positional or named arguments")
258
        if not self.toplevel:
259
            self.raiseError(node, _error.NotSupported, "embedded function definition")
260
        self.toplevel = False
261
        self.visitChildNodes(node, *args)
262
 
263
    def visitIf(self, node, *args):
264
        node.ignore = False
265
        if len(node.tests) == 1 and not node.else_:
266
            test = node.tests[0][0]
267
            if isinstance(test, compiler.ast.Name):
268
                if test.name == '__debug__':
269
                    node.ignore = True
270
                    return # skip
271
        for test, suite in node.tests:
272
            self.visit(test)
273
            self.visit(suite)
274
        if node.else_:
275
            self.visit(node.else_)
276
 
277
    def visitPrintnl(self, node, *args):
278
        if node.dest is not None:
279
            self.raiseError(node, _error.NotSupported, "printing to a file with >> syntax")
280
        self.visitChildNodes(node, *args)
281
 
282
    def visitPrint(self, node, *args):
283
        self.raiseError(node, _error.NotSupported, "printing without newline")
284
 
285
    # visitPrint = visitPrintnl
286
 
287
 
288
 
289
def getNrBits(obj):
290
    if hasattr(obj, '_nrbits'):
291
        return obj._nrbits
292
    return None
293
 
294
def hasType(obj, theType):
295
    if isinstance(obj, theType):
296
        return True
297
    if isinstance(obj, Signal):
298
        if isinstance(obj._val, theType):
299
            return True
300
    return False
301
 
302
 
303
class ReferenceStack(list):
304
    def push(self):
305
        self.append(Set())
306
    def add(self, item):
307
        self[-1].add(item)
308
    def __contains__(self, item):
309
        for s in self:
310
            if item in s:
311
                return True
312
        return False
313
 
314
# auxiliary types to aid type checking
315
## class _EdgeDetector(object):
316
##     pass
317
 
318
class _Ram(object):
319
    __slots__ = ['elObj', 'depth']
320
 
321
 
322
class _Rom(object):
323
    __slots__ = ['rom']
324
    def __init__(self, rom):
325
        self.rom = rom
326
 
327
 
328
def _maybeNegative(obj):
329
    if hasattr(obj, '_min') and (obj._min is not None) and (obj._min < 0):
330
        return True
331
    if isinstance(obj, (int, long)) and obj < 0:
332
        return True
333
    return False
334
 
335
re_str = re.compile(r"[^%]+")
336
re_ConvSpec = re.compile(r"%(?P[-]?)(?P[0-9]*)(?P[sd])")
337
 
338
class ConvSpec(object):
339
    def __init__(self, **kwargs):
340
        self.justified = "RIGHT"
341
        self.width = 0
342
        self.conv = str
343
        if kwargs['justified'] == '-':
344
            self.justified = "LEFT"
345
        if kwargs['width']:
346
            self.width = int(kwargs['width'])
347
        if kwargs['conv'] == 'd':
348
            self.conv = int
349
 
350
defaultConvSpec = ConvSpec(**re_ConvSpec.match(r"%s").groupdict())
351
 
352
 
353
class _AnalyzeVisitor(_ConversionMixin):
354
 
355
    def __init__(self, ast):
356
        ast.sigdict = {}
357
        ast.vardict = {}
358
        ast.inputs = Set()
359
        ast.outputs = Set()
360
        ast.argnames = []
361
        ast.kind = None
362
        ast.hasYield = 0
363
        ast.hasRom = False
364
        ast.hasPrint = False
365
        self.ast = ast
366
        self.labelStack = []
367
        self.refStack = ReferenceStack()
368
        self.globalRefs = Set()
369
 
370
 
371
    def binaryOp(self, node, *args):
372
        self.visit(node.left)
373
        self.visit(node.right)
374
        node.obj = int(-1)
375
        node.signed = node.left.signed or node.right.signed
376
    visitAdd = binaryOp
377
    visitFloorDiv = binaryOp
378
    visitLeftShift = binaryOp
379
    visitMul = binaryOp
380
    visitPower = binaryOp
381
    visitMod = binaryOp
382
    visitRightShift = binaryOp
383
    visitSub = binaryOp
384
 
385
    def multiBitOp(self, node, *args):
386
        node.signed = False
387
        for n in node.nodes:
388
            self.visit(n)
389
            if n.signed:
390
                node.signed = True
391
        node.obj = None
392
        for n in node.nodes:
393
            if node.obj is None:
394
                node.obj = n.obj
395
            elif isinstance(node.obj, type(n.obj)):
396
                node.obj = n.obj
397
    def visitBitand(self, node, *args):
398
        self.multiBitOp(node, *args)
399
    def visitBitor(self, node, *args):
400
        self.multiBitOp(node, *args)
401
    def visitBitxor(self, node, *args):
402
        self.multiBitOp(node, *args)
403
    def multiLogicalOp(self, node, *args):
404
        for n in node.nodes:
405
            self.visit(n, *args)
406
        for n in node.nodes:
407
            if not hasType(n.obj, bool):
408
                self.raiseError(node, _error.NotSupported, "non-boolean argument in logical operator")
409
        node.obj = bool()
410
    def visitAnd(self, node, *args):
411
        self.multiLogicalOp(node, *args)
412
    def visitOr(self, node, *args):
413
        self.multiLogicalOp(node, *args)
414
 
415
    # unaryOp's
416
    def visitInvert(self, node, *args):
417
        self.visit(node.expr)
418
        node.obj = node.expr.obj
419
        node.signed = node.expr.signed
420
    def visitNot(self, node, *args):
421
        self.visit(node.expr)
422
        node.obj = bool()
423
        print(node.expr)
424
        node.signed = node.expr.signed
425
    def visitUnaryAdd(self, node, *args):
426
        self.visit(node.expr)
427
        node.obj = int(-1)
428
        node.signed = node.expr.signed
429
    def visitUnarySub(self, node, *args):
430
        self.visit(node.expr)
431
        node.obj = int(-1)
432
        node.signed = node.expr.signed
433
        if isinstance(node.expr, astNode.Const):
434
            node.signed = True
435
 
436
    def visitAssAttr(self, node, access=_access.OUTPUT, *args):
437
        if node.attrname != 'next':
438
            self.raiseError(node, _error.NotSupported, "attribute assignment")
439
        self.ast.kind = _kind.TASK
440
        self.visit(node.expr, _access.OUTPUT)
441
 
442
    def visitAssign(self, node, access=_access.OUTPUT, *args):
443
        target, expr = node.nodes[0], node.expr
444
        self.visit(target, _access.OUTPUT)
445
        if isinstance(target, astNode.AssName):
446
            self.visit(expr, _access.INPUT, _kind.DECLARATION)
447
            node.kind = _kind.DECLARATION
448
            n = target.name
449
            if n in self.ast.sigdict:
450
                self.raiseError(node, _error.ShadowingVar)
451
            obj = self.getObj(expr)
452
            if obj is None:
453
                self.raiseError(node, _error.TypeInfer, n)
454
            if isinstance(obj, intbv):
455
                if len(obj) == 0:
456
                    self.raiseError(node, _error.IntbvBitWidth, n)
457
##                 if obj._min < 0:
458
##                     self.raiseError(node, _error.IntbvSign, n)
459
                    if obj._min < 0:
460
                        _signed = True
461
            if n in self.ast.vardict:
462
                curObj = self.ast.vardict[n]
463
                if isinstance(obj, type(curObj)):
464
                    pass
465
                elif isinstance(curObj, type(obj)):
466
                     self.ast.vardict[n] = obj
467
                else:
468
                    self.raiseError(node, _error.TypeMismatch, n)
469
                if getNrBits(obj) != getNrBits(curObj):
470
                    self.raiseError(node, _error.NrBitsMismatch, n)
471
            else:
472
                self.ast.vardict[n] = obj
473
        else:
474
            self.visit(expr, _access.INPUT)
475
 
476
    def visitAssName(self, node, *args):
477
        n = node.name
478
        if n in ("__verilog__", "__vhdl__"):
479
            self.raiseError(node, _error.NotSupported,
480
                            "%s in generator function" % n)
481
        # XXX ?
482
        if n in self.globalRefs:
483
            self.raiseError(node, _error.UnboundLocal, n)
484
        self.refStack.add(n)
485
 
486
    def visitAugAssign(self, node, access=_access.INPUT, *args):
487
        self.visit(node.node, _access.INOUT)
488
        self.visit(node.expr, _access.INPUT)
489
 
490
    def visitBreak(self, node, *args):
491
        self.labelStack[-2].isActive = True
492
 
493
    def visitCallFunc(self, node, *args):
494
        self.visit(node.node)
495
        for arg in node.args:
496
            self.visit(arg, _access.UNKNOWN)
497
        argsAreInputs = True
498
        f = self.getObj(node.node)
499
        node.obj = None
500
        node.signed = False
501
        if type(f) is type and issubclass(f, intbv):
502
            node.obj = self.getVal(node)
503
        elif f is concat:
504
            node.obj = self.getVal(node)
505
        elif f is len:
506
            node.obj = int(0) # XXX
507
        elif f is bool:
508
            node.obj = bool()
509
        elif f in (int, long, ord):
510
            node.obj = int(-1)
511
##         elif f in (posedge , negedge):
512
##             node.obj = _EdgeDetector()
513
        elif f is delay:
514
            node.obj = delay(0)
515
        ### suprize: identity comparison on unbound methods doesn't work in python 2.5??
516
        elif f == intbv.signed:
517
            node.obj = int(-1)
518
            node.signed = True
519
        elif f in myhdlObjects:
520
            pass
521
        elif f in builtinObjects:
522
            pass
523
        elif type(f) is FunctionType:
524
            argsAreInputs = False
525
            s = inspect.getsource(f)
526
            s = s.lstrip()
527
            ast = compiler.parse(s)
528
            # print ast
529
            fname = f.__name__
530
            ast.name = _Label(fname)
531
            ast.sourcefile = inspect.getsourcefile(f)
532
            ast.lineoffset = inspect.getsourcelines(f)[1]-1
533
            ast.symdict = f.func_globals.copy()
534
            if fname in self.ast.callstack:
535
                self.raiseError(node, _error.NotSupported, "Recursive call")
536
            ast.callstack = self.ast.callstack[:]
537
            ast.callstack.append(fname)
538
            # handle free variables
539
            if f.func_code.co_freevars:
540
                for n, c in zip(f.func_code.co_freevars, f.func_closure):
541
                    obj = _cell_deref(c)
542
                    if not  isinstance(obj, (int, long, Signal)):
543
                        self.raiseError(node, _error.FreeVarTypeError, n)
544
                    ast.symdict[n] = obj
545
            v = _NotSupportedVisitor(ast)
546
            compiler.walk(ast, v)
547
            v = _AnalyzeFuncVisitor(ast, node.args)
548
            compiler.walk(ast, v)
549
            node.obj = ast.returnObj
550
            node.ast = ast
551
            for i, arg in enumerate(node.args):
552
                if isinstance(arg, astNode.Keyword):
553
                    n = arg.name
554
                else: # Name
555
                    n = ast.argnames[i]
556
                if n in ast.outputs:
557
                    self.visit(arg, _access.OUTPUT)
558
                if n in ast.inputs:
559
                    self.visit(arg, _access.INPUT)
560
        elif type(f) is MethodType:
561
            self.raiseError(node,_error.NotSupported, "method call: '%s'" % f.__name__)
562
        else:
563
            raise AssertionError("Unexpected callable")
564
        if argsAreInputs:
565
            for arg in node.args:
566
                self.visit(arg, _access.INPUT)
567
 
568
    def visitCompare(self, node, *args):
569
        node.obj = bool()
570
        node.signed = False
571
        for n in node.getChildNodes():
572
            self.visit(n, *args)
573
            if n.signed:
574
                node.signed = True
575
        op, arg = node.ops[0]
576
##         node.expr.target = self.getObj(arg)
577
##         arg.target = self.getObj(node.expr)
578
        # detect specialized case for the test
579
        if op == '==' and isinstance(node.expr, astNode.Name):
580
            n = node.expr.name
581
            # check wether it can be a case
582
            if isinstance(arg.obj, EnumItemType):
583
                node.case = (node.expr, arg.obj)
584
            # check whether it can be part of an edge check
585
            elif n in self.ast.sigdict:
586
                sig = self.ast.sigdict[n]
587
                v = self.getValue(arg)
588
                if v is not None:
589
                    if v == 0:
590
                        node.edge = sig.negedge
591
                    elif v == 1:
592
                        node.edge = sig.posedge
593
 
594
 
595
    def visitConst(self, node, *args):
596
        node.signed = False
597
        if node.value in (0, 1):
598
            node.obj = bool(node.value)
599
        elif isinstance(node.value, (int, str)):
600
            node.obj = node.value
601
        else:
602
            node.obj = None
603
 
604
    def visitContinue(self, node, *args):
605
        self.labelStack[-1].isActive = True
606
 
607
    def visitFor(self, node, *args):
608
        node.breakLabel = _Label("BREAK")
609
        node.loopLabel = _Label("LOOP")
610
        self.labelStack.append(node.breakLabel)
611
        self.labelStack.append(node.loopLabel)
612
        self.refStack.push()
613
        self.visit(node.assign)
614
        var = node.assign.name
615
        self.ast.vardict[var] = int(-1)
616
 
617
        cf = node.list
618
        self.visit(cf)
619
        self.require(node, isinstance(cf, astNode.CallFunc), "Expected (down)range call")
620
        f = self.getObj(cf.node)
621
        self.require(node, f in (range, downrange), "Expected (down)range call")
622
 
623
        self.visit(node.body, *args)
624
        self.refStack.pop()
625
        self.require(node, node.else_ is None, "for-else not supported")
626
        self.labelStack.pop()
627
        self.labelStack.pop()
628
 
629
    def visitFunction(self, node, *args):
630
        raise AssertionError("subclass must implement this")
631
 
632
    def visitGetattr(self, node, *args):
633
        self.visit(node.expr, *args)
634
        node.obj = None
635
        node.signed = False
636
        if isinstance(node.expr, astNode.Name):
637
            n = node.expr.name
638
            if (n not in self.ast.vardict) and (n not in self.ast.symdict):
639
                raise AssertionError("attribute target: %s" % n)
640
        obj = node.expr.obj
641
        if isinstance(obj, Signal):
642
            if node.attrname == 'posedge':
643
                node.obj = obj.posedge
644
            elif node.attrname == 'negedge':
645
                node.obj = obj.negedge
646
            elif node.attrname in ('val', 'next'):
647
                node.obj = obj.val
648
        if isinstance(obj, (intbv, Signal)):
649
            if node.attrname == 'min':
650
                node.obj = obj.min
651
            elif node.attrname == 'max':
652
                node.obj = obj.max
653
            elif node.attrname == 'signed':
654
                node.obj = intbv.signed
655
        if isinstance(obj, EnumType):
656
#           print("Object:" + `obj`)
657
#           print("Name:" + `node.attrname`)
658
            assert hasattr(obj, node.attrname)
659
            node.obj = getattr(obj, node.attrname)
660
            if obj not in _enumTypeSet:
661
                _enumTypeSet.add(obj)
662
                suf = _genUniqueSuffix.next()
663
                obj._setName(n+suf)
664
        if node.obj is None: # attribute lookup failed
665
            self.raiseError(node, _error.UnsupportedAttribute, node.attrname)
666
 
667
 
668
 
669
    def visitIf(self, node, *args):
670
        if node.ignore:
671
            return
672
        for test, suite in node.tests:
673
            self.visit(test, *args)
674
            self.refStack.push()
675
            self.visit(suite, *args)
676
            self.refStack.pop()
677
        if node.else_:
678
            self.refStack.push()
679
            self.visit(node.else_, *args)
680
            self.refStack.pop()
681
        # check whether the if can be mapped to a (parallel) case
682
        node.isCase = node.isFullCase = False
683
        test1 = node.tests[0][0]
684
        if not hasattr(test1, 'case'):
685
            return
686
        var1, item1 = test1.case
687
        # don't infer a case if there's no elsif test
688
        if not node.tests[1:]:
689
            return
690
        choices = Set()
691
        choices.add(item1._index)
692
        for test, suite in node.tests[1:]:
693
            if not hasattr(test, 'case'):
694
                return
695
            var, item = test.case
696
            if var.name != var1.name or type(item) is not type(item1):
697
                return
698
            if item._index in choices:
699
                return
700
            choices.add(item._index)
701
        node.isCase = True
702
        node.caseVar = var1
703
        if (len(choices) == item1._nritems) or (node.else_ is not None):
704
            node.isFullCase = True
705
 
706
    def visitListComp(self, node, *args):
707
        mem = node.obj = _Ram()
708
        self.visit(node.expr, _access.INPUT, _kind.DECLARATION)
709
        mem.elObj = self.getObj(node.expr)
710
        if not isinstance(mem.elObj, intbv) or not len(mem.elObj) > 0:
711
            self.raiseError(node, _error.UnsupportedListComp)
712
        cf = node.quals[0].list
713
        self.visit(cf)
714
        if not isinstance(cf, astNode.CallFunc):
715
            self.raiseError(node, _error.UnsupportedListComp)
716
        f = self.getObj(cf.node)
717
        if f is not range or len(cf.args) != 1:
718
            self.raiseError(node, _error.UnsupportedListComp)
719
        mem.depth = cf.args[0].obj
720
 
721
    def visitName(self, node, access=_access.INPUT, *args):
722
        n = node.name
723
        node.obj = None
724
        if n not in self.refStack:
725
            if n in self.ast.vardict:
726
                self.raiseError(node, _error.UnboundLocal, n)
727
            self.globalRefs.add(n)
728
        if n in self.ast.sigdict:
729
            node.obj = sig = self.ast.sigdict[n]
730
            if not isinstance(sig, Signal):
731
                # print "not a signal: %s" % n
732
                pass
733
            else:
734
                if sig._type is bool:
735
                    node.edge = sig.posedge
736
            if access == _access.INPUT:
737
                self.ast.inputs.add(n)
738
            elif access == _access.OUTPUT:
739
                self.ast.kind = _kind.TASK
740
                if n in self.ast.outputs:
741
                    node.kind = _kind.REG
742
                self.ast.outputs.add(n)
743
            elif access == _access.UNKNOWN:
744
                pass
745
            else:
746
                raise AssertionError
747
        if n in self.ast.vardict:
748
            obj = self.ast.vardict[n]
749
            if access == _access.INOUT:
750
                # upgrade bool to int for augmented assignments
751
                if isinstance(obj, bool):
752
                    obj = int(0)
753
                    self.ast.vardict[n] = obj
754
            node.obj = obj
755
        elif n in self.ast.symdict:
756
            node.obj = self.ast.symdict[n]
757
            if _isTupleOfInts(node.obj):
758
                node.obj = _Rom(node.obj)
759
                self.ast.hasRom = True
760
            elif isinstance(node.obj, int):
761
                node.value = node.obj
762
        elif n in __builtin__.__dict__:
763
            node.obj = __builtin__.__dict__[n]
764
        else:
765
            pass
766
        node.signed = _maybeNegative(node.obj)
767
##         node.target = node.obj
768
 
769
    def visitReturn(self, node, *args):
770
        self.raiseError(node, _error.NotSupported, "return statement")
771
 
772
    def visitPrintnl(self, node, *args):
773
        self.ast.hasPrint = True
774
        f = []
775
        nr = 0
776
        a = []
777
        for n in node.nodes:
778
            if isinstance(n, astNode.Mod) and \
779
               (isinstance(n.left, astNode.Const) and isinstance(n.left.value, str)):
780
                if isinstance(n.right, astNode.Tuple):
781
                    a.extend(n.right.nodes)
782
                else:
783
                    a.append(n.right)
784
                s = n.left.value
785
                while s:
786
                    if not s:
787
                        break
788
                    if s[:2] == "%%":
789
                        f.append("%")
790
                        s = s[2:]
791
                        continue
792
                    m = re_ConvSpec.match(s)
793
                    if m:
794
                        c = ConvSpec(**m.groupdict())
795
                        if c.justified != "RIGHT":
796
                            self.raiseError(node,_error.UnsupportedFormatString,
797
                                            "format justification specification: %s" %s)
798
                        if c.width != 0:
799
                            self.raiseError(node,_error.UnsupportedFormatString,
800
                                            "format width specification: %s" %s)
801
                        f.append(c)
802
                        s = s[m.end():]
803
                        nr += 1
804
                        continue
805
                    m = re_str.match(s)
806
                    if m:
807
                        f.append(s[:m.end()])
808
                        s = s[m.end():]
809
                        continue
810
                    self.raiseError(node, _error.UnsupportedFormatString, "%s" % s)
811
            else:
812
                f.append(defaultConvSpec)
813
                a.append(n)
814
                nr += 1
815
            f.append(" ")
816
        # remove last single space if it exists
817
        if f:
818
            f.pop()
819
        node.format = f
820
        node.args = a
821
        if len(node.args) < nr:
822
            self.raiseError(node, _error.FormatString, "not enough arguments")
823
        if len(node.args) > nr:
824
            self.raiseError(node, _error.FormatString, "too many arguments")
825
        self.visitChildNodes(node, *args)
826
 
827
    visitPrint = visitPrintnl
828
 
829
    def visitSlice(self, node, access=_access.INPUT, kind=_kind.NORMAL, *args):
830
        node.signed = False
831
        self.visit(node.expr, access)
832
        node.obj = self.getObj(node.expr)
833
        if node.lower:
834
            self.visit(node.lower, _access.INPUT)
835
        if node.upper:
836
            self.visit(node.upper, _access.INPUT)
837
        if isinstance(node.obj , intbv):
838
            if kind == _kind.DECLARATION:
839
                self.require(node.lower, "Expected leftmost index")
840
                leftind = self.getVal(node.lower)
841
                if node.upper:
842
                    rightind = self.getVal(node.upper)
843
                else:
844
                    rightind = 0
845
                node.obj = node.obj[leftind:rightind]
846
 
847
 
848
    def visitSubscript(self, node, access=_access.INPUT, *args):
849
        self.visit(node.expr, access)
850
        assert len(node.subs) == 1
851
        self.visit(node.subs[0], _access.INPUT)
852
        if isinstance(node.expr.obj, _Ram):
853
            if node.flags == 'OP_ASSIGN':
854
                self.raiseError(node, _error.ListElementAssign)
855
            else:
856
                node.obj = node.expr.obj.elObj
857
        elif _isMem(node.expr.obj):
858
            node.obj = node.expr.obj[0]
859
        elif isinstance(node.expr.obj, _Rom):
860
            node.obj = int(-1)
861
        elif isinstance(node.expr.obj, intbv):
862
            node.obj = bool()
863
        else:
864
            node.obj = bool() # XXX default
865
        node.signed = _maybeNegative(node.obj)
866
 
867
    def visitTuple(self, node, *args):
868
        node.signed = False
869
        self.visitChildNodes(node, *args)
870
 
871
    def visitWhile(self, node, *args):
872
        node.breakLabel = _Label("BREAK")
873
        node.loopLabel = _Label("LOOP")
874
        self.labelStack.append(node.breakLabel)
875
        self.labelStack.append(node.loopLabel)
876
        self.visit(node.test, *args)
877
        self.refStack.push()
878
        self.visit(node.body, *args)
879
        self.refStack.pop()
880
        y = node.body.nodes[0]
881
        if isinstance(y, astNode.Discard):
882
            y = y.expr
883
        if node.test.obj == True and \
884
           isinstance(y, astNode.Yield) and \
885
           not self.ast.hasYield > 1 and \
886
           not isinstance(self.getObj(y.value), delay):
887
            node.kind = _kind.ALWAYS
888
            self.ast.senslist = y.senslist
889
        self.require(node, node.else_ is None, "while-else not supported")
890
        self.labelStack.pop()
891
        self.labelStack.pop()
892
 
893
    def visitYield(self, node, *args):
894
        self.ast.hasYield += 1
895
        n = node.value
896
        self.visit(n)
897
        senslist = []
898
        if isinstance(n, astNode.Tuple):
899
            for n in n.nodes:
900
                if not isinstance(n.obj, (Signal, _WaiterList)):
901
                    self.raiseError(node, _error.UnsupportedYield)
902
                senslist.append(n.obj)
903
        elif isinstance(n.obj, (Signal, _WaiterList, delay)):
904
            senslist = [n.obj]
905
        elif _isMem(n.obj):
906
            senslist = n.obj
907
        else:
908
            self.raiseError(node, _error.UnsupportedYield)
909
        node.senslist = senslist
910
 
911
##     def visitModule(self, node, *args):
912
##         self.visit(node.node)
913
##         for n in self.ast.inputs:
914
##             s = self.ast.sigdict[n]
915
##             s._read = True
916
 
917
 
918
 
919
class _AnalyzeBlockVisitor(_AnalyzeVisitor):
920
 
921
    def __init__(self, ast):
922
        _AnalyzeVisitor.__init__(self, ast)
923
        for n, v in self.ast.symdict.items():
924
            if isinstance(v, Signal):
925
                self.ast.sigdict[n] = v
926
 
927
    def visitFunction(self, node, *args):
928
        self.refStack.push()
929
        self.visit(node.code)
930
        self.ast.kind = _kind.ALWAYS
931
        for n in node.code.nodes[:-1]:
932
            if not self.getKind(n) == _kind.DECLARATION:
933
                self.ast.kind = _kind.INITIAL
934
                break
935
        if self.ast.kind == _kind.ALWAYS:
936
            w = node.code.nodes[-1]
937
            if not self.getKind(w) == _kind.ALWAYS:
938
                self.ast.kind = _kind.INITIAL
939
        self.refStack.pop()
940
 
941
    def visitModule(self, node, *args):
942
        self.visit(node.node)
943
        for n in self.ast.outputs:
944
            s = self.ast.sigdict[n]
945
            if s._driven:
946
                self.raiseError(node, _error.SigMultipleDriven, n)
947
            s._driven = "reg"
948
        for n in self.ast.inputs:
949
            s = self.ast.sigdict[n]
950
            s._read = True
951
 
952
    def visitReturn(self, node, *args):
953
        ### value should be None
954
        if isinstance(node.value, astNode.Const) and node.value.value is None:
955
            obj = None
956
        elif isinstance(node.value, astNode.Name) and node.value.name == 'None':
957
            obj = None
958
        else:
959
            self.raiseError(node, _error.NotSupported, "return value other than None")
960
 
961
 
962
class _AnalyzeAlwaysCombVisitor(_AnalyzeBlockVisitor):
963
 
964
    def __init__(self, ast, senslist):
965
        _AnalyzeBlockVisitor.__init__(self, ast)
966
        self.ast.senslist = senslist
967
 
968
    def visitFunction(self, node, *args):
969
          self.refStack.push()
970
          self.visit(node.code)
971
          self.ast.kind = _kind.SIMPLE_ALWAYS_COMB
972
          for n in node.code.nodes:
973
              if isinstance(n, astNode.Assign) and \
974
                 isinstance(n.nodes[0], astNode.AssAttr) and \
975
                 self.getKind(n.nodes[0].expr) != _kind.REG:
976
                  pass
977
              else:
978
                  self.ast.kind = _kind.ALWAYS_COMB
979
                  return
980
          # rom access is expanded into a case statement
981
          if self.ast.hasRom:
982
              self.ast.kind = _kind.ALWAYS_COMB
983
          self.refStack.pop()
984
 
985
    def visitModule(self, node, *args):
986
        _AnalyzeBlockVisitor.visitModule(self, node, *args)
987
        if self.ast.kind == _kind.SIMPLE_ALWAYS_COMB:
988
            for n in self.ast.outputs:
989
                s = self.ast.sigdict[n]
990
                s._driven = "wire"
991
 
992
 
993
class _AnalyzeAlwaysDecoVisitor(_AnalyzeBlockVisitor):
994
 
995
    def __init__(self, ast, senslist):
996
        _AnalyzeBlockVisitor.__init__(self, ast)
997
        self.ast.senslist = senslist
998
 
999
    def visitFunction(self, node, *args):
1000
          self.refStack.push()
1001
          self.visit(node.code)
1002
          self.ast.kind = _kind.ALWAYS_DECO
1003
          self.refStack.pop()
1004
 
1005
 
1006
 
1007
class _AnalyzeFuncVisitor(_AnalyzeVisitor):
1008
 
1009
    def __init__(self, ast, args):
1010
        _AnalyzeVisitor.__init__(self, ast)
1011
        self.args = args
1012
        self.ast.hasReturn = False
1013
        self.ast.returnObj = None
1014
 
1015
    def visitFunction(self, node, *args):
1016
        self.refStack.push()
1017
        argnames = node.argnames
1018
        for i, arg in enumerate(self.args):
1019
            if isinstance(arg, astNode.Keyword):
1020
                n = arg.name
1021
                self.ast.symdict[n] = self.getObj(arg.expr)
1022
            else: # Name
1023
                n = argnames[i]
1024
                self.ast.symdict[n] = self.getObj(arg)
1025
            self.ast.argnames.append(n)
1026
        for n, v in self.ast.symdict.items():
1027
            if isinstance(v, (Signal, intbv)):
1028
                self.ast.sigdict[n] = v
1029
        self.visit(node.code)
1030
        self.refStack.pop()
1031
        if self.ast.hasYield:
1032
            self.raiseError(node, _error.NotSupported,
1033
                            "call to a generator function")
1034
        if self.ast.kind == _kind.TASK:
1035
            if self.ast.returnObj is not None:
1036
                self.raiseError(node, _error.NotSupported,
1037
                                "function with side effects and return value")
1038
        else:
1039
            if self.ast.returnObj is None:
1040
                self.raiseError(node, _error.NotSupported,
1041
                                "pure function without return value")
1042
 
1043
 
1044
    def visitReturn(self, node, *args):
1045
        self.visit(node.value, _access.INPUT, _kind.DECLARATION, *args)
1046
        if isinstance(node.value, astNode.Const) and node.value.value is None:
1047
            obj = None
1048
        elif isinstance(node.value, astNode.Name) and node.value.name == 'None':
1049
            obj = None
1050
        elif node.value.obj is not None:
1051
            obj = node.value.obj
1052
        else:
1053
            self.raiseError(node, _error.ReturnTypeInfer)
1054
        if isinstance(obj, intbv) and len(obj) == 0:
1055
            self.raiseError(node, _error.ReturnIntbvBitWidth)
1056
        if self.ast.hasReturn:
1057
            returnObj = self.ast.returnObj
1058
            if isinstance(obj, type(returnObj)):
1059
                pass
1060
            elif isinstance(returnObj, type(obj)):
1061
                self.ast.returnObj = obj
1062
            else:
1063
                self.raiseError(node, _error.ReturnTypeMismatch)
1064
            if getNrBits(obj) != getNrBits(returnObj):
1065
                self.raiseError(node, _error.ReturnNrBitsMismatch)
1066
        else:
1067
            self.ast.returnObj = obj
1068
            self.ast.hasReturn = True
1069
 
1070
 
1071
def _analyzeTopFunc(func, *args, **kwargs):
1072
    s = inspect.getsource(func)
1073
    s = s.lstrip()
1074
    ast = compiler.parse(s)
1075
    v = _AnalyzeTopFuncVisitor(*args, **kwargs)
1076
    compiler.walk(ast, v)
1077
    return v
1078
 
1079
 
1080
class _AnalyzeTopFuncVisitor(object):
1081
 
1082
    def __init__(self, *args, **kwargs):
1083
        self.args = args
1084
        self.kwargs = kwargs
1085
        self.name = None
1086
        self.argdict = {}
1087
 
1088
    def visitFunction(self, node):
1089
        self.name = node.name
1090
        argnames = node.argnames
1091
        i=-1
1092
        for i, arg in enumerate(self.args):
1093
            if isinstance(arg, Signal):
1094
                n = argnames[i]
1095
                self.argdict[n] = arg
1096
        for n in argnames[i+1:]:
1097
            if n in self.kwargs:
1098
                arg = self.kwargs[n]
1099
                if isinstance(arg, Signal):
1100
                    self.argdict[n] = arg
1101
        self.argnames = [n for n in argnames if n in self.argdict]
1102
 
1103
 

powered by: WebSVN 2.1.0

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