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)))
def getBindSubset(self, termname, visited_sources=set()): term = self.getTerm(termname) if term is None: raise verror.DefinitionError('No such signal') bindlist = self.getBindlist(termname) nextsources = visited_sources.copy() ret_binds = collections.OrderedDict() for bind in bindlist: if not termname in ret_binds: ret_binds[termname] = [] ret_binds[termname].append(bind) if bind.isClockEdge(): clock_name = bind.getClockName() if clock_name != util.toTermname( (self.topmodule, self.clock_name)): r_binds, r_sources = self.getBindSubset( clock_name, nextsources) nextsources |= r_sources ret_binds = util.dictlistmerge(ret_binds, r_binds) sources = self.getBindSources(termname) for source in sources: if source in visited_sources: continue nextsources.add(source) r_binds, r_sources = self.getBindSubset(source, nextsources) ret_binds = util.dictlistmerge(ret_binds, r_binds) nextsources |= r_sources return ret_binds, nextsources
def walkBind(self, name, step=0): termname = util.toTermname(name) if not termname in self.terms: raise verror.DefinitionError('No such signals: %s' % str(name)) tree = self.getTree(termname) walked_tree = self.walkTree(tree, visited=set(), step=step) return replace.replaceUndefined(walked_tree, termname)
def generate(self, signalname, identical=False, walk=True, step=1, reorder=False, delay=False): termname = util.toTermname(signalname) tree = self.treewalker.getTree(termname) if tree is None: raise verror.DefinitionError('No such signals: %s' % str(signalname)) if walk: tree = self.treewalker.walkTree(tree, visited=set(), step=step, delay=delay) if reorder: tree = reorder.reorder(tree) tree = self.optimizer.optimize(tree) if reorder: tree = reorder.reorder(tree) tree = replace.replaceUndefined(tree, termname) name = self.rename(signalname) self.identical = identical self.add_node(name, label=signalname) self.visit(tree, name)
def __init__(self, nextnodes, operator): self.nextnodes = nextnodes self.operator = operator for n in nextnodes: if n is None: raise verror.DefinitionError()
def addBind(self, name, bind): if name is None: raise verror.DefinitionError('Bind name is empty') if not name in self.binddict: self.binddict[name] = [bind,] else: self.setBind(name, bind)
def __init__(self, tree, dest, msb=None, lsb=None, ptr=None, alwaysinfo=None, parameterinfo=''): self.tree = tree self.dest = dest self.msb = msb self.lsb = lsb self.ptr = ptr self.alwaysinfo = alwaysinfo self.parameterinfo = parameterinfo if dest is None: raise verror.DefinitionError('Bind dest is empty')
def searchConstantDefinition(self, key, name): foundkey, founddef = self.frames.searchConstantDefinition(key, name) if foundkey is not None: return foundkey + ScopeLabel(name, 'signal'), founddef foundkey, founddef = self.frames.searchSignalDefinition(key, name) if foundkey is not None: return foundkey + ScopeLabel(name, 'signal'), founddef if foundkey is None: raise verror.DefinitionError('constant value not found: %s' % name)
def setBind(self, name, bind): if name is None: raise verror.DefinitionError('Bind name is empty') currentbindlist = self.binddict[name] c_i = 0 for c in currentbindlist: if c.msb == bind.msb and c.msb == bind.msb and c.ptr == bind.ptr: self.binddict[name][c_i].tree = bind.tree return c_i += 1 self.binddict[name] = currentbindlist + [bind,]
def getSources(self, tree): if tree is None: return set() if isinstance(tree, DFConstant): return set() if isinstance(tree, DFUndefined): return set() if isinstance(tree, DFEvalValue): return set() if isinstance(tree, DFTerminal): return set([ tree.name, ]) if isinstance(tree, DFBranch): ret = set() ret |= self.getSources(tree.condnode) ret |= self.getSources(tree.truenode) ret |= self.getSources(tree.falsenode) return ret if isinstance(tree, DFOperator): nextnodes = [] for n in tree.nextnodes: nextnodes.extend(self.getSources(n)) return set(nextnodes) if isinstance(tree, DFPartselect): ret = set() ret |= self.getSources(tree.var) ret |= self.getSources(tree.msb) ret |= self.getSources(tree.lsb) return ret if isinstance(tree, DFPointer): ret = set() ret |= self.getSources(tree.var) ret |= self.getSources(tree.ptr) return ret if isinstance(tree, DFConcat): nextnodes = [] for n in tree.nextnodes: nextnodes.extend(self.getSources(n)) return set(nextnodes) if isinstance(tree, DFDelay): ret = set() ret |= self.getSources(tree.nextnode) return ret raise verror.DefinitionError('Undefined Node Type: %s : %s' % (str(type(tree)), str(tree)))
def addFrame(self, scopename, frametype='none', alwaysinfo=None, condition=None, module=False, functioncall=False, taskcall=False, generate=False, always=False, initial=False, loop=None, loop_iter=None, modulename=None): scopechain = self.toScopeChain(scopename) if scopechain in self.dict: raise verror.DefinitionError('Already Exists: %s' % str(scopechain)) ret = self.current previous = self.current if len(previous) > 0: self.dict[previous].setNext(scopechain) self.dict[scopechain] = Frame(scopechain, previous, frametype=frametype, alwaysinfo=alwaysinfo, condition=condition, module=module, functioncall=functioncall, taskcall=taskcall, generate=generate, always=always, initial=initial, loop=loop, loop_iter=loop_iter, modulename=modulename) self.current = scopechain return ret
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)))
def getTermtype(self, termname): term = self.getTerm(termname) if term is None: raise verror.DefinitionError('No such Term: %s' % termname) return term.termtype
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)))
def getConstant(self, name): if not name in self.constlist: raise verror.DefinitionError('constant value not found: %s' % str(name)) return self.constlist[name]
def getParamNames(self, name): if name not in self.dict: raise verror.DefinitionError('No such module: %s' % name) return self.dict[name].getParamNames()
def addDefinition(self, name, definition): if name in self.dict: raise verror.DefinitionError('Already defined: %s' % name) self.dict[name] = DefinitionInfo(name, definition) self.current = name
def tocode(self, dest='dest'): raise verror.DefinitionError('DFDelay does not support tocode()')