예제 #1
0
    def tocode(self):
        flatname = util.toFlatname(self.name)
        scope = self.getScope(self.name)
        code = ''
        if self.isTopmodule(scope):
            if signaltype.isInput(self.termtype): code += 'input '
            elif signaltype.isInout(self.termtype): code += 'inout '
            elif signaltype.isOutput(self.termtype): code += 'output '
        else:
            if signaltype.isInput(self.termtype): code += 'wire '
            elif signaltype.isInout(self.termtype): code += 'wire '
            elif signaltype.isOutput(self.termtype) and not signaltype.isReg(self.termtype): code += 'wire '

        if signaltype.isReg(self.termtype): code += 'reg '
        if signaltype.isRegArray(self.termtype): code += 'reg '
        if signaltype.isWire(self.termtype): code += 'wire '
        if signaltype.isWireArray(self.termtype): code += 'wire '
        if signaltype.isInteger(self.termtype): code += 'integer '
        if signaltype.isFunction(self.termtype): code += 'wire '
        if signaltype.isRename(self.termtype): code += 'wire '

        if (not signaltype.isInteger(self.termtype) and
            self.msb is not None and self.lsb is not None):
            code += '[' + self.msb.tocode(None) + ':' + self.lsb.tocode(None) + '] '
        code += flatname # signal name
        if self.lenmsb is not None and self.lenlsb is not None:
            code += ' [' + self.lenmsb.tocode() + ':' + self.lenlsb.tocode(flatname) + ']'
        code += ';\n'
        return code
예제 #2
0
    def getWidth(self, node):
        if node is None: return self.default_width
        if isinstance(node, DFUndefined):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFHighImpedance):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFIntConst):
            return node.width()
        if isinstance(node, DFConstant):
            return self.default_width
        if isinstance(node, DFEvalValue):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFTerminal):
            term = self.getTerm(node.name)
            msb = self.optimizeConstant(term.msb).value
            lsb = self.optimizeConstant(term.lsb).value
            width = abs(msb - lsb) + 1
            return width

        if isinstance(node, DFBranch):
            truewidth = self.getWidth(node.truenode)
            falsewidth = self.getWidth(node.falsenode)
            return max(truewidth, falsewidth)

        if isinstance(node, DFPartselect):
            msb = self.optimizeConstant(node.msb).value
            lsb = self.optimizeConstant(node.lsb).value
            width = abs(msb - lsb) + 1
            return width
        if isinstance(node, DFOperator):
            if node.operator in self.compare_ops: return 1
            if node.operator == 'Land' or node.operator == 'Lor': return 1
            maxwidth = 0
            for n in node.nextnodes:
                width = self.getWidth(n)
                if maxwidth < width: maxwidth = width
            return maxwidth
        if isinstance(node, DFConcat):
            sumwidth = 0
            for n in node.nextnodes:
                width = self.getWidth(n)
                sumwidth += width
            return sumwidth
        if isinstance(node, DFPointer):
            if not isinstance(node.var, DFTerminal): return 1
            term = self.getTerm(node.var.name)
            if signaltype.isRegArray(term.termtype) or signaltype.isWireArray(
                    term.termtype):
                msb = self.optimizeConstant(term.msb).value
                lsb = self.optimizeConstant(term.lsb).value
                width = abs(msb - lsb) + 1
                return width
            return 1
        if isinstance(tree, DFSyscall):
            return self.default_width

        raise FormatError('Illegal Pointer in getWidth()')
예제 #3
0
파일: merge.py 프로젝트: zyy5833/Pyverilog
 def getAssignType(self, termname, bind):
     termtype = self.getTermtype(termname)
     if signaltype.isWire(termtype):
         return 'assign'
     if signaltype.isWireArray(termtype):
         return 'assign'
     if signaltype.isReg(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isRegArray(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isInteger(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isParameter(termtype):
         return 'parameter'
     if signaltype.isLocalparam(termtype):
         return 'localparam'
     if signaltype.isOutput(termtype):
         return 'assign'
     if signaltype.isInput(termtype):
         return 'assign'
     if signaltype.isFunction(termtype):
         return 'assign'
     if signaltype.isRename(termtype):
         return 'assign'
     if signaltype.isGenvar(termtype):
         return 'genvar'
     raise verror.DefinitionError('Unexpected Assignment Type: %s : %s' %
                                  (str(termname), str(termtype)))
예제 #4
0
파일: merge.py 프로젝트: ewelex/Pyverilog
 def getAssignType(self, termname, bind):
     termtype = self.getTermtype(termname)
     if signaltype.isWire(termtype):
         return 'assign'
     if signaltype.isWireArray(termtype):
         return 'assign'
     if signaltype.isReg(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isRegArray(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isInteger(termtype):
         if bind.isClockEdge(): return 'clockedge'
         return 'combination'
     if signaltype.isParameter(termtype):
         return 'parameter'
     if signaltype.isLocalparam(termtype):
         return 'localparam'
     if signaltype.isOutput(termtype):
         return 'assign'
     if signaltype.isInput(termtype):
         return 'assign'
     if signaltype.isFunction(termtype):
         return 'assign'
     if signaltype.isRename(termtype):
         return 'assign'
     if signaltype.isGenvar(termtype):
         return 'genvar'
     raise verror.DefinitionError('Unexpected Assignment Type: %s : %s' % (str(termname), str(termtype)))
예제 #5
0
    def getWidth(self, node):
        if node is None: return self.default_width
        if isinstance(node, DFUndefined):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFHighImpedance):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFIntConst):
            return node.width()
        if isinstance(node, DFConstant):
            return self.default_width
        if isinstance(node, DFEvalValue):
            if node.width is not None: return node.width
            return self.default_width
        if isinstance(node, DFTerminal):
            term = self.getTerm(node.name)
            msb = self.optimizeConstant(term.msb).value
            lsb = self.optimizeConstant(term.lsb).value
            width = abs(msb - lsb) + 1
            return width

        if isinstance(node, DFBranch):
            truewidth = self.getWidth(node.truenode)
            falsewidth = self.getWidth(node.falsenode)
            return max(truewidth, falsewidth)

        if isinstance(node, DFPartselect):
            msb = self.optimizeConstant(node.msb).value
            lsb = self.optimizeConstant(node.lsb).value
            width = abs(msb - lsb) + 1
            return width
        if isinstance(node, DFOperator):
            if node.operator in self.compare_ops: return 1
            if node.operator == 'Land' or node.operator == 'Lor': return 1
            maxwidth = 0
            for n in node.nextnodes:
                width = self.getWidth(n)
                if maxwidth < width: maxwidth = width
            return maxwidth
        if isinstance(node, DFConcat):
            sumwidth = 0
            for n in node.nextnodes:
                width = self.getWidth(n)
                sumwidth += width
            return sumwidth
        if isinstance(node, DFPointer):
            if not isinstance(node.var, DFTerminal): return 1
            term = self.getTerm(node.var.name)
            if signaltype.isRegArray(term.termtype) or signaltype.isWireArray(term.termtype):
                msb = self.optimizeConstant(term.msb).value
                lsb = self.optimizeConstant(term.lsb).value
                width = abs(msb - lsb) + 1
                return width
            return 1
        if isinstance(tree, DFSyscall):
            return self.default_width
        
        raise FormatError('Illegal Pointer in getWidth()')
 def getFuncdict(self, termname, delaycnt=0):
     termtype = self.getTermtype(termname)
     if not self.isClockEdge(termname): return {}, 0
     if signaltype.isRename(termtype): return {}, 0
     if signaltype.isRegArray(termtype): return {}, 0 # currently unsupported
     tree = self.makeTree(termname)
     funcdict = splitter.split(tree)
     funcdict = splitter.remove_reset_condition(funcdict)
     if len(funcdict) == 1 and len(funcdict.keys()[0]) == 0:
         next_term = funcdict.values()[0]
         if isinstance(next_term, DFTerminal):
             return self.getFuncdict(next_term.name, delaycnt+1)
     return funcdict, delaycnt
예제 #7
0
 def getFuncdict(self, termname, delaycnt=0):
     termtype = self.getTermtype(termname)
     if not self.isClockEdge(termname): return {}, 0
     if signaltype.isRename(termtype): return {}, 0
     if signaltype.isRegArray(termtype): return {}, 0 # currently unsupported
     tree = self.makeTree(termname)
     funcdict = splitter.split(tree)
     funcdict = splitter.remove_reset_condition(funcdict)
     if len(funcdict) == 1 and len(funcdict.keys()[0]) == 0:
         next_term = funcdict.values()[0]
         if isinstance(next_term, DFTerminal):
             return self.getFuncdict(next_term.name, delaycnt+1)
     return funcdict, delaycnt
예제 #8
0
파일: merge.py 프로젝트: zyy5833/Pyverilog
    def getTree(self, termname, ptr=None):
        bindlist = self.getResolvedBindlist(termname)
        bindlist = self.getOptimizedBindlist(bindlist)
        if bindlist is None: return None
        if len(bindlist) == 0: return None

        termtype = self.getTermtype(termname)

        if signaltype.isRegArray(termtype) or signaltype.isWireArray(termtype):
            discretebinds = {}
            for bind in bindlist:
                if isinstance(bind.ptr, DFEvalValue):
                    ptrval = bind.ptr.value
                    if not ptrval in discretebinds: discretebinds[ptrval] = []
                    discretebinds[ptrval] += [bind]
                else:
                    if not 'any' in discretebinds: discretebinds['any'] = []
                    discretebinds['any'] += [bind]

            if 'any' in discretebinds:
                return DFTerminal(termname)

            if isinstance(ptr, DFEvalValue):
                if len(discretebinds[ptr.value]) == 0:
                    return None
                if len(discretebinds[ptr.value]) == 1:
                    return discretebinds[ptr.value][0].tree
                return self.getMergedTree(discretebinds[ptr.value])

            minptr = min(list(discretebinds.keys()))
            maxptr = max(list(discretebinds.keys()))
            ret = None
            for c in range(minptr, maxptr + 1):
                truetree = None
                if len(discretebinds[c]) == 0:
                    continue
                if len(discretebinds[c]) == 1:
                    truetree = discretebinds[c][0].tree
                else:
                    truetree = self.getMergedTree(discretebinds[c])
                ret = DFBranch(DFOperator((DFEvalValue(c), ptr), 'Eq'),
                               truetree, ret)
            return ret

        if len(bindlist) == 1:
            return bindlist[0].tree
        new_tree = self.getMergedTree(bindlist)
        return self.optimizer.optimize(new_tree)
예제 #9
0
파일: merge.py 프로젝트: ewelex/Pyverilog
    def getTree(self, termname, ptr=None):
        bindlist = self.getResolvedBindlist(termname)
        bindlist = self.getOptimizedBindlist(bindlist)
        if bindlist is None: return None
        if len(bindlist) == 0: return None

        termtype = self.getTermtype(termname)

        if signaltype.isRegArray(termtype) or signaltype.isWireArray(termtype):
            discretebinds = {}
            for bind in bindlist:
                if isinstance(bind.ptr, DFEvalValue):
                    ptrval = bind.ptr.value
                    if not ptrval in discretebinds: discretebinds[ptrval] = []
                    discretebinds[ptrval] += [bind]
                else:
                    if not 'any' in discretebinds: discretebinds['any'] = []
                    discretebinds['any'] += [bind]

            if 'any' in discretebinds:
                return DFTerminal(termname)

            if isinstance(ptr, DFEvalValue):
                if len(discretebinds[ptr.value]) == 0:
                    return None
                if len(discretebinds[ptr.value]) == 1:
                    return discretebinds[ptr.value][0].tree
                return self.getMergedTree(discretebinds[ptr.value])

            minptr = min(list(discretebinds.keys()))
            maxptr = max(list(discretebinds.keys()))
            ret = None
            for c in range(minptr, maxptr+1):
                truetree = None
                if len(discretebinds[c]) == 0:
                    continue
                if len(discretebinds[c]) == 1:
                    truetree = discretebinds[c][0].tree
                else:
                    truetree = self.getMergedTree(discretebinds[c])
                ret = DFBranch(DFOperator((DFEvalValue(c), ptr),'Eq'), truetree, ret)
            return ret

        if len(bindlist) == 1:
            return bindlist[0].tree
        new_tree = self.getMergedTree(bindlist)
        return self.optimizer.optimize(new_tree) 
예제 #10
0
파일: merge.py 프로젝트: zyy5833/Pyverilog
 def splitBind(self, bind, splitpos):
     tree = bind.tree
     msb = self.optimizer.optimizeConstant(bind.msb)
     lsb = self.optimizer.optimizeConstant(bind.lsb)
     ptr = self.optimizer.optimizeConstant(bind.ptr)
     if ptr is not None and msb is None or lsb is None:
         termtype = self.getTermtype(bind.dest)
         if signaltype.isRegArray(termtype) or signaltype.isWireArray(
                 termtype):
             msb = self.optimizer.optimizeConstant(copy.deepcopy(term.msb))
             lsb = self.optimizer.optimizeConstant(copy.deepcopy(term.lsb))
         else:
             msb = copy.deepcopy(ptr)
             lsb = copy.deepcopy(ptr)
     if ptr is None and msb is None or lsb is None:
         term = self.getTerm(bind.dest)
         msb = self.optimizer.optimizeConstant(copy.deepcopy(term.msb))
         lsb = self.optimizer.optimizeConstant(copy.deepcopy(term.lsb))
     if splitpos > lsb.value and splitpos <= msb.value:  # split
         right_lsb = lsb.value
         right_msb = splitpos - 1
         right_width = splitpos - lsb.value
         left_lsb = splitpos
         left_msb = msb.value
         left_width = msb.value - splitpos + 1
         right_tree = reorder.reorder(
             DFPartselect(copy.deepcopy(tree), DFEvalValue(right_width - 1),
                          DFEvalValue(0)))
         left_tree = reorder.reorder(
             DFPartselect(copy.deepcopy(tree), DFEvalValue(msb.value),
                          DFEvalValue(msb.value - left_width + 1)))
         right_tree = self.optimizer.optimize(right_tree)
         left_tree = self.optimizer.optimize(left_tree)
         left_bind = copy.deepcopy(bind)
         left_bind.tree = left_tree
         left_bind.msb = DFEvalValue(left_msb)
         left_bind.lsb = DFEvalValue(left_lsb)
         right_bind = copy.deepcopy(bind)
         right_bind.tree = right_tree
         right_bind.msb = DFEvalValue(right_msb)
         right_bind.lsb = DFEvalValue(right_lsb)
         return left_bind, right_bind
     return bind, None
예제 #11
0
파일: merge.py 프로젝트: ewelex/Pyverilog
 def splitBind(self, bind, splitpos):
     tree = bind.tree
     msb = self.optimizer.optimizeConstant(bind.msb)
     lsb = self.optimizer.optimizeConstant(bind.lsb)
     ptr = self.optimizer.optimizeConstant(bind.ptr)
     if ptr is not None and msb is None or lsb is None:
         termtype = self.getTermtype(bind.dest)
         if signaltype.isRegArray(termtype) or signaltype.isWireArray(termtype):
             msb = self.optimizer.optimizeConstant(copy.deepcopy(term.msb))
             lsb = self.optimizer.optimizeConstant(copy.deepcopy(term.lsb))
         else:
             msb = copy.deepcopy(ptr)
             lsb = copy.deepcopy(ptr)
     if ptr is None and msb is None or lsb is None:
         term = self.getTerm(bind.dest)
         msb = self.optimizer.optimizeConstant(copy.deepcopy(term.msb))
         lsb = self.optimizer.optimizeConstant(copy.deepcopy(term.lsb))
     if splitpos > lsb.value and splitpos <= msb.value: # split
         right_lsb = lsb.value
         right_msb = splitpos - 1
         right_width = splitpos - lsb.value
         left_lsb = splitpos
         left_msb = msb.value
         left_width = msb.value - splitpos + 1
         right_tree = reorder.reorder(DFPartselect(copy.deepcopy(tree), DFEvalValue(right_width-1), DFEvalValue(0)))
         left_tree = reorder.reorder(DFPartselect(copy.deepcopy(tree), DFEvalValue(msb.value), DFEvalValue(msb.value-left_width+1)))
         right_tree = self.optimizer.optimize(right_tree)
         left_tree = self.optimizer.optimize(left_tree)
         left_bind = copy.deepcopy(bind)
         left_bind.tree = left_tree
         left_bind.msb = DFEvalValue(left_msb)
         left_bind.lsb = DFEvalValue(left_lsb)
         right_bind = copy.deepcopy(bind)
         right_bind.tree = right_tree
         right_bind.msb = DFEvalValue(right_msb)
         right_bind.lsb = DFEvalValue(right_lsb)
         return left_bind, right_bind
     return bind, None
예제 #12
0
    def optimizeConstant(self, tree):
        if tree is None: return None
        if isinstance(tree, DFBranch):
            condnode = self.optimizeConstant(tree.condnode)
            truenode = self.optimizeConstant(tree.truenode)
            falsenode = self.optimizeConstant(tree.falsenode)
            if isinstance(condnode, DFEvalValue):
                if self.isCondTrue(condnode): return truenode
                return falsenode
            return DFBranch(condnode, truenode, falsenode)

        if isinstance(tree, DFEvalValue):
            return tree
        if isinstance(tree, DFUndefined):
            return tree
        if isinstance(tree, DFHighImpedance):
            return tree
        if isinstance(tree, DFDelay):
            raise FormatError('Can not evaluate and optimize a DFDelay')
            #return tree

        if isinstance(tree, DFIntConst):
            if 'x' in tree.value or 'z' in tree.value:
                return DFUndefined(tree.width())
            if 'X' in tree.value or 'Z' in tree.value:
                return DFUndefined(tree.width())
            return DFEvalValue(tree.eval(), tree.width())
        if isinstance(tree, DFFloatConst):
            return DFEvalValue(tree.eval(), self.default_width, isfloat=True)
        if isinstance(tree, DFStringConst):
            return DFEvalValue(tree.eval(), None, isstring=True)
        if isinstance(tree, DFConstant):
            if 'x' in tree.value or 'z' in tree.value:
                return DFUndefined()
            if 'X' in tree.value or 'Z' in tree.value:
                return DFUndefined()
            return DFEvalValue(tree.eval(), self.default_width)

        if isinstance(tree, DFOperator):
            nextnodes_rslts, all_const = self.evalNextnodes(tree.nextnodes)
            if all_const:
                evalop = self.evalOperator(tree.operator, nextnodes_rslts)
                if evalop is not None: return evalop
            return DFOperator(tuple(nextnodes_rslts), tree.operator)

        if isinstance(tree, DFTerminal):
            if not self.hasConstant(tree.name): return tree
            msb = self.getTerm(tree.name).msb
            lsb = self.getTerm(tree.name).lsb
            const = self.getConstant(tree.name)
            constwidth = const.width
            if msb is not None and lsb is not None:
                msb_val = self.optimizeConstant(msb)
                lsb_val = self.optimizeConstant(lsb)
                if isinstance(msb_val, DFEvalValue) and isinstance(lsb_val, DFEvalValue):
                    constwidth = msb_val.value - lsb_val.value + 1
            return DFEvalValue(const.value, constwidth)

        if isinstance(tree, DFConcat):
            nextnodes_rslts, all_const = self.evalNextnodes(tree.nextnodes)
            if all_const:
                evalcc = self.evalConcat(nextnodes_rslts)
                if evalcc is not None: return evalcc
            return DFConcat(tuple(nextnodes_rslts))

        if isinstance(tree, DFPartselect):
            var = self.optimizeConstant(tree.var)
            msb = self.optimizeConstant(tree.msb)
            lsb = self.optimizeConstant(tree.lsb)
            if isinstance(var, DFEvalValue) and isinstance(msb, DFEvalValue) and isinstance(msb, DFEvalValue):
                evalcc = self.evalPartselect(var, msb, lsb)
                return evalcc
            return DFPartselect(var, msb, lsb)

        if isinstance(tree, DFPointer):
            if not isinstance(tree.var, DFTerminal): return tree
            term = self.getTerm(tree.var.name)
            var = self.optimizeConstant(tree.var)
            ptr = self.optimizeConstant(tree.ptr)
            if signaltype.isRegArray(term.termtype) or signaltype.isWireArray(term.termtype):
                return DFPointer(var, ptr)
            if isinstance(var, DFEvalValue) and isinstance(ptr, DFEvalValue):
                evalcc = self.evalPointer(var, ptr)
                return evalcc
            return DFPointer(var, ptr)
        
        if isinstance(tree, DFSyscall):
            return DFSyscall(tree.syscall, tuple([ self.optimizeConstant(n) for n in tree.nextnodes ]))
        
        raise verror.DefinitionError('Can not optimize the tree: %s %s' %
                                     (str(type(tree)), str(tree)))
예제 #13
0
    def walkTree(self,
                 tree,
                 visited=set([]),
                 step=0,
                 delay=False,
                 msb=None,
                 lsb=None,
                 ptr=None):
        if tree is None:
            return DFUndefined(32)

        if isinstance(tree, DFUndefined):
            return tree

        if isinstance(tree, DFHighImpedance):
            return tree

        if isinstance(tree, DFConstant):
            return tree

        if isinstance(tree, DFEvalValue):
            return tree

        if isinstance(tree, DFTerminal):
            scope = util.getScope(tree.name)
            termname = tree.name
            if termname in visited: return tree

            termtype = self.getTermtype(termname)
            if util.isTopmodule(scope) and signaltype.isInput(termtype):
                return tree

            nptr = None
            if signaltype.isRegArray(termtype) or signaltype.isWireArray(
                    termtype):
                if ptr is None:
                    raise verror.FormatError(
                        'Array variable requires an pointer.')
                if msb is not None and lsb is not None: return tree
                nptr = ptr

            nextstep = step
            if signaltype.isReg(termtype) or signaltype.isRegArray(termtype):
                if (not self.isCombination(termname)
                        and not signaltype.isRename(termtype)
                        and nextstep == 0):
                    return tree
                if (not self.isCombination(termname)
                        and not signaltype.isRename(termtype)):
                    nextstep -= 1

            return self.walkTree(self.getTree(termname, nptr), visited | set([
                termname,
            ]), nextstep, delay)

        if isinstance(tree, DFBranch):
            condnode = self.walkTree(tree.condnode, visited, step, delay)
            truenode = self.walkTree(tree.truenode, visited, step, delay)
            falsenode = self.walkTree(tree.falsenode, visited, step, delay)
            return DFBranch(condnode, truenode, falsenode)

        if isinstance(tree, DFOperator):
            nextnodes = []
            for n in tree.nextnodes:
                nextnodes.append(self.walkTree(n, visited, step, delay))
            return DFOperator(tuple(nextnodes), tree.operator)

        if isinstance(tree, DFPartselect):
            msb = self.walkTree(tree.msb, visited, step, delay)
            lsb = self.walkTree(tree.lsb, visited, step, delay)
            var = self.walkTree(tree.var,
                                visited,
                                step,
                                delay,
                                msb=msb,
                                lsb=lsb)
            return DFPartselect(var, msb, lsb)

        if isinstance(tree, DFPointer):
            ptr = self.walkTree(tree.ptr, visited, step, delay)
            var = self.walkTree(tree.var, visited, step, delay, ptr=ptr)
            if isinstance(tree.var, DFTerminal):
                termtype = self.getTermtype(tree.var.name)
                if ((signaltype.isRegArray(termtype)
                     or signaltype.isWireArray(termtype))
                        and not (isinstance(var, DFTerminal)
                                 and var.name == tree.var.name)):
                    return var
            return DFPointer(var, ptr)

        if isinstance(tree, DFConcat):
            nextnodes = []
            for n in tree.nextnodes:
                nextnodes.append(self.walkTree(n, visited, step, delay))
            return DFConcat(tuple(nextnodes))

        raise verror.DefinitionError('Undefined Node Type: %s : %s' %
                                     (str(type(tree)), str(tree)))
예제 #14
0
    def optimizeConstant(self, tree):
        if tree is None: return None
        if isinstance(tree, DFBranch):
            condnode = self.optimizeConstant(tree.condnode)
            truenode = self.optimizeConstant(tree.truenode)
            falsenode = self.optimizeConstant(tree.falsenode)
            if isinstance(condnode, DFEvalValue):
                if self.isCondTrue(condnode): return truenode
                return falsenode
            return DFBranch(condnode, truenode, falsenode)

        if isinstance(tree, DFEvalValue):
            return tree
        if isinstance(tree, DFUndefined):
            return tree
        if isinstance(tree, DFHighImpedance):
            return tree
        if isinstance(tree, DFDelay):
            raise FormatError('Can not evaluate and optimize a DFDelay')
            #return tree

        if isinstance(tree, DFIntConst):
            if 'x' in tree.value or 'z' in tree.value:
                return DFUndefined(tree.width())
            return DFEvalValue(tree.eval(), tree.width())
        if isinstance(tree, DFFloatConst):
            return DFEvalValue(tree.eval(), self.default_width, isfloat=True)
        if isinstance(tree, DFStringConst):
            return DFEvalValue(tree.eval(), None, isstring=True)
        if isinstance(tree, DFConstant):
            if 'x' in tree.value or 'z' in tree.value:
                return DFUndefined()
            return DFEvalValue(tree.eval(), self.default_width)

        if isinstance(tree, DFOperator):
            nextnodes_rslts, all_const = self.evalNextnodes(tree.nextnodes)
            if all_const:
                evalop = self.evalOperator(tree.operator, nextnodes_rslts)
                if evalop is not None: return evalop
            return DFOperator(tuple(nextnodes_rslts), tree.operator)

        if isinstance(tree, DFTerminal):
            if not self.hasConstant(tree.name): return tree
            msb = self.getTerm(tree.name).msb
            lsb = self.getTerm(tree.name).lsb
            const = self.getConstant(tree.name)
            constwidth = const.width
            if msb is not None and lsb is not None:
                msb_val = self.optimizeConstant(msb)
                lsb_val = self.optimizeConstant(lsb)
                if isinstance(msb_val, DFEvalValue) and isinstance(
                        lsb_val, DFEvalValue):
                    constwidth = msb_val.value - lsb_val.value + 1
            return DFEvalValue(const.value, constwidth)

        if isinstance(tree, DFConcat):
            nextnodes_rslts, all_const = self.evalNextnodes(tree.nextnodes)
            if all_const:
                evalcc = self.evalConcat(nextnodes_rslts)
                if evalcc is not None: return evalcc
            return DFConcat(tuple(nextnodes_rslts))

        if isinstance(tree, DFPartselect):
            var = self.optimizeConstant(tree.var)
            msb = self.optimizeConstant(tree.msb)
            lsb = self.optimizeConstant(tree.lsb)
            if isinstance(var, DFEvalValue) and isinstance(
                    msb, DFEvalValue) and isinstance(msb, DFEvalValue):
                evalcc = self.evalPartselect(var, msb, lsb)
                return evalcc
            return DFPartselect(var, msb, lsb)

        if isinstance(tree, DFPointer):
            if not isinstance(tree.var, DFTerminal): return tree
            term = self.getTerm(tree.var.name)
            var = self.optimizeConstant(tree.var)
            ptr = self.optimizeConstant(tree.ptr)
            if signaltype.isRegArray(term.termtype) or signaltype.isWireArray(
                    term.termtype):
                return DFPointer(var, ptr)
            if isinstance(var, DFEvalValue) and isinstance(ptr, DFEvalValue):
                evalcc = self.evalPointer(var, ptr)
                return evalcc
            return DFPointer(var, ptr)

        if isinstance(tree, DFSyscall):
            return DFSyscall(
                tree.syscall,
                tuple([self.optimizeConstant(n) for n in tree.nextnodes]))

        raise verror.DefinitionError('Can not optimize the tree: %s %s' %
                                     (str(type(tree)), str(tree)))
예제 #15
0
    def walkTree(self, tree, visited=set([]), step=0, delay=False, msb=None, lsb=None, ptr=None):
        if tree is None:
            return DFUndefined(32)

        if isinstance(tree, DFUndefined):
            return tree

        if isinstance(tree, DFHighImpedance):
            return tree

        if isinstance(tree, DFConstant):
            return tree

        if isinstance(tree, DFEvalValue):
            return tree

        if isinstance(tree, DFTerminal):
            scope = util.getScope(tree.name)
            termname = tree.name
            if termname in visited:
                return tree

            termtype = self.getTermtype(termname)
            if util.isTopmodule(scope) and signaltype.isInput(termtype):
                return tree

            nptr = None
            if signaltype.isRegArray(termtype) or signaltype.isWireArray(termtype):
                if ptr is None:
                    raise verror.FormatError("Array variable requires an pointer.")
                if msb is not None and lsb is not None:
                    return tree
                nptr = ptr

            nextstep = step
            if signaltype.isReg(termtype) or signaltype.isRegArray(termtype):
                if not self.isCombination(termname) and not signaltype.isRename(termtype) and nextstep == 0:
                    return tree
                if not self.isCombination(termname) and not signaltype.isRename(termtype):
                    nextstep -= 1

            return self.walkTree(self.getTree(termname, nptr), visited | set([termname]), nextstep, delay)

        if isinstance(tree, DFBranch):
            condnode = self.walkTree(tree.condnode, visited, step, delay)
            truenode = self.walkTree(tree.truenode, visited, step, delay)
            falsenode = self.walkTree(tree.falsenode, visited, step, delay)
            return DFBranch(condnode, truenode, falsenode)

        if isinstance(tree, DFOperator):
            nextnodes = []
            for n in tree.nextnodes:
                nextnodes.append(self.walkTree(n, visited, step, delay))
            return DFOperator(tuple(nextnodes), tree.operator)

        if isinstance(tree, DFPartselect):
            msb = self.walkTree(tree.msb, visited, step, delay)
            lsb = self.walkTree(tree.lsb, visited, step, delay)
            var = self.walkTree(tree.var, visited, step, delay, msb=msb, lsb=lsb)
            if isinstance(var, DFPartselect):
                child_lsb = self.getTerm(str(tree.var)).lsb.eval()
                return DFPartselect(
                    var.var,
                    DFIntConst(str(msb.eval() + var.lsb.eval() - child_lsb)),
                    DFIntConst(str(lsb.eval() + var.lsb.eval() - child_lsb)),
                )
            return DFPartselect(var, msb, lsb)

        if isinstance(tree, DFPointer):
            ptr = self.walkTree(tree.ptr, visited, step, delay)
            var = self.walkTree(tree.var, visited, step, delay, ptr=ptr)
            if isinstance(tree.var, DFTerminal):
                termtype = self.getTermtype(tree.var.name)
                if (signaltype.isRegArray(termtype) or signaltype.isWireArray(termtype)) and not (
                    isinstance(var, DFTerminal) and var.name == tree.var.name
                ):
                    return var
            return DFPointer(var, ptr)

        if isinstance(tree, DFConcat):
            nextnodes = []
            for n in tree.nextnodes:
                nextnodes.append(self.walkTree(n, visited, step, delay))
            return DFConcat(tuple(nextnodes))

        raise verror.DefinitionError("Undefined Node Type: %s : %s" % (str(type(tree)), str(tree)))