def _visit_Instance_body(self, node, nodename): if node.module in primitives: return self._visit_Instance_primitive(node) if nodename == '': raise verror.FormatError("Module %s requires an instance name" % node.module) current = self.stackInstanceFrame(nodename, node.module) self.setInstanceSimpleConstantTerms() scope = self.frames.getCurrent() paramnames = self.moduleinfotable.getParamNames(node.module) for paramnames_i, param in enumerate(node.parameterlist): paramname = paramnames[ paramnames_i] if param.paramname is None else param.paramname if paramname not in paramnames: raise verror.FormatError("No such parameter: %s in %s" % (paramname, nodename)) value = self.optimize(self.getTree(param.argname, current)) name, definition = self.searchConstantDefinition(scope, paramname) self.setConstant(name, value) self.setInstanceConstants() self.setInstanceConstantTerms() self.visit(self.moduleinfotable.getDefinition(node.module)) self.frames.setCurrent(current)
def getAlwaysStatus(self, left_value): ptr = self.current frame = self.dict[ptr] alwaysinfo = frame.getAlwaysInfo() while True: if frame.isFunctioncall(): return None if frame.isTaskcall(): return None if not frame.isAlways(): return None if alwaysinfo is not None: if left_value in frame.load_const_dict.keys( ) and frame.load_const_dict[left_value]: return alwaysinfo elif alwaysinfo.reset_edge != 'sync': raise verror.FormatError('Illegal sensitivity list') #ex. #As follows, RST is reset signal for reg1 but clock for reg2. #This is rearded as illegal sensitivity list. # always @(posedge CLK or posedge RST) begin # if(RST) begin # reg1 <= 8'd0; # end else begin # reg1 <= 8'd0; # reg2 <= 8'd1; # end # end else: return self.to_noreset(alwaysinfo) ptr = self.dict[ptr].previous frame = self.dict[ptr] alwaysinfo = frame.getAlwaysInfo()
def infer(op, node): # if not isinstance(node, DFEvalValue): return None if not isinstance(node, DFEvalValue): raise verror.FormatError('Can not infer the value from non DFEvalValue object') val = node.value funcname = 'op_' + op opfunc = getattr(this, funcname, op_None) return opfunc(val)
def setInstanceConstantTerms(self): current = self.frames.getCurrent() for name, definitions in self.frames.getConsts(current).items(): if len(definitions) > 1: raise verror.FormatError("Multiple definitions for Constant") for definition in definitions: term = self.makeConstantTerm(name, definition, current) self.setConstantTerm(name, term)
def toScopeChain(self, blocklabel): scopelist = [] for b in blocklabel.labellist: if b.loop is not None: loop = self.optimize(b.loop) if not isinstance(loop, DFEvalValue): raise verror.FormatError('Loop iterator should be constant') scopelist.append(ScopeLabel(b.name, 'for', loop)) scopelist.append(ScopeLabel(b.name, 'any')) return ScopeChain(scopelist)
def _visit_Instance_array(self, node): if node.name == '': raise verror.FormatError("Module %s requires an instance name" % node.module) current = self.frames.getCurrent() msb = self.optimize(self.getTree(node.array.msb, current)).value lsb = self.optimize(self.getTree(node.array.lsb, current)).value for i in range(lsb, msb + 1): nodename = node.name + '_' + str(i) self._visit_Instance_body(node, nodename)
def setInstanceSimpleConstantTerms(self): current = self.frames.getCurrent() for name, definitions in self.frames.getConsts(current).items(): if len(definitions) > 1: raise verror.FormatError("Multiple definitions for Constant") for definition in definitions: simple_definition = copy.deepcopy(definition) if simple_definition.width is not None: simple_definition.width.msb = None simple_definition.width.lsb = None term = self.makeConstantTerm(name, simple_definition, current) self.setConstantTerm(name, term)
def visit_ForStatement(self, node): ## pre-statement current = self.frames.getCurrent() pre_right = self.getTree(node.pre.right, current) pre_right_value = self.optimize(pre_right) loop = pre_right_value.value self.frames.setForPre() self.visit(node.pre) self.frames.unsetForPre() label = self.labels.get(self.frames.getLabelKey('for')) #loop = 0 while True: ## cond-statement current = self.frames.getCurrent() tree = self.getTree(node.cond, current) rslt = self.optimize(tree) if not isinstance(rslt, DFEvalValue): raise verror.FormatError( ("Can not process the for-statement. " "for-condition should be evaluated statically.")) # loop termination if rslt.value <= 0: break ## main-statement current = self.frames.addFrame( ScopeLabel(label, 'for', loop), frametype='for', functioncall=self.frames.isFunctioncall(), taskcall=self.frames.isTaskcall(), generate=self.frames.isGenerate(), always=self.frames.isAlways(), initial=self.frames.isInitial(), loop=loop, loop_iter=self.frames.getForIter()) self.visit(node.statement) self.frames.setCurrent(current) ## post-statement current = self.frames.getCurrent() post_right = self.getTree(node.post.right, current) post_right_value = self.optimize(post_right) loop = post_right_value.value self.frames.setForPost() self.visit(node.post) self.frames.unsetForPost()
def mergeTree(self, first, second): if isinstance(first, DFBranch) and isinstance(second, DFBranch): cond_fst = self.optimizer.optimize(first.condnode) cond_snd = self.optimizer.optimize(second.condnode) if cond_fst == cond_snd: return DFBranch( cond_fst, self.mergeTree(first.truenode, second.truenode), self.mergeTree(first.falsenode, second.falsenode)) appended = copy.deepcopy(first) return DFBranch(cond_snd, self.appendTail(appended, second.truenode), self.appendTail(appended, second.falsenode)) if first is not None and second is None: return first if first is None and second is not None: return second if isinstance(first, DFBranch) and second is None: return first if first is None and isinstance(second, DFBranch): return second if isinstance(first, DFBranch) and not isinstance(second, DFBranch): cond_fst = self.optimizer.optimize(first.condnode) appended = copy.deepcopy(second) return DFBranch(cond_fst, self.appendTail(appended, first.truenode), self.appendTail(appended, first.falsenode)) if not isinstance(first, DFBranch) and isinstance(second, DFBranch): cond_snd = self.optimizer.optimize(second.condnode) appended = copy.deepcopy(first) return DFBranch(cond_snd, self.appendTail(appended, second.truenode), self.appendTail(appended, second.falsenode)) if not isinstance(first, DFBranch) and not isinstance( second, DFBranch): return second raise verror.FormatError('Can not merge trees.')
def visit_IfStatement(self, node): if (self.frames.isGenerate() and not self.frames.isAlways() and not self.frames.isInitial() and not self.frames.isFunctioncall() and not self.frames.isTaskcall() and not self.frames.isFunctiondef() and not self.frames.isTaskdef()): # generate-if statement current = self.frames.getCurrent() tree = self.getTree(node.cond, current) rslt = self.optimize(tree) if not isinstance(rslt, DFEvalValue): raise verror.FormatError("Can not resolve generate-if condition") if rslt.value > 0: label = self._if_true(node) else: label = self.labels.get(self.frames.getLabelKey('if')) self._if_false(node, label) return label = self._if_true(node) self._if_false(node, label)
def setInstanceConstants(self): current = self.frames.getCurrent() all_passed = False while not all_passed: all_passed = True for name, definitions in self.frames.getConsts(current).items(): if len(definitions) > 1: raise verror.FormatError("Multiple definitions for Constant") if self.hasConstant(name): continue for definition in definitions: if isinstance(definition, Genvar): continue value = self.optimize(self.getTree(definition.value, current)) if not isinstance(value, DFEvalValue): all_passed = False continue self.setConstant(name, value)
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 op_None(val): raise verror.FormatError('Unsupported Comparator')
def makeDFTree(self, node, scope): if isinstance(node, str): return self.searchConstantValue(scope, node) if isinstance(node, Identifier): if node.scope is not None: const = self.searchScopeConstantValue(node.scope, node.name) return const return self.searchConstantValue(scope, node.name) if isinstance(node, IntConst): return DFIntConst(node.value) if isinstance(node, FloatConst): return DFFloatConst(node.value) if isinstance(node, StringConst): return DFStringConst(node.value) if isinstance(node, Cond): true_df = self.makeDFTree(node.true_value, scope) false_df = self.makeDFTree(node.false_value, scope) cond_df = self.makeDFTree(node.cond, scope) if isinstance(cond_df, DFBranch): return reorder.insertCond(cond_df, true_df, false_df) return DFBranch(cond_df, true_df, false_df) if isinstance(node, UnaryOperator): right_df = self.makeDFTree(node.right, scope) if isinstance(right_df, DFBranch): return reorder.insertUnaryOp(right_df, node.__class__.__name__) return DFOperator((right_df, ), node.__class__.__name__) if isinstance(node, Operator): left_df = self.makeDFTree(node.left, scope) right_df = self.makeDFTree(node.right, scope) if isinstance(left_df, DFBranch) or isinstance(right_df, DFBranch): return reorder.insertOp(left_df, right_df, node.__class__.__name__) return DFOperator(( left_df, right_df, ), node.__class__.__name__) if isinstance(node, Partselect): var_df = self.makeDFTree(node.var, scope) msb_df = self.makeDFTree(node.msb, scope) lsb_df = self.makeDFTree(node.lsb, scope) if isinstance(var_df, DFBranch): return reorder.insertPartselect(var_df, msb_df, lsb_df) return DFPartselect(var_df, msb_df, lsb_df) if isinstance(node, Pointer): var_df = self.makeDFTree(node.var, scope) ptr_df = self.makeDFTree(node.ptr, scope) if (isinstance(var_df, DFTerminal) and (signaltype.isRegArray(self.getTermtype(var_df.name)) or signaltype.isWireArray(self.getTermtype(var_df.name)))): return DFPointer(var_df, ptr_df) return DFPartselect(var_df, ptr_df, copy.deepcopy(ptr_df)) if isinstance(node, Concat): nextnodes = [] for n in node.list: nextnodes.append(self.makeDFTree(n, scope)) for n in nextnodes: if isinstance(n, DFBranch): return reorder.insertConcat(tuple(nextnodes)) return DFConcat(tuple(nextnodes)) if isinstance(node, Repeat): nextnodes = [] times = self.optimize(self.getTree(node.times, scope)).value value = self.makeDFTree(node.value, scope) for i in range(int(times)): nextnodes.append(copy.deepcopy(value)) return DFConcat(tuple(nextnodes)) if isinstance(node, SystemCall): if node.syscall == 'unsigned': return self.makeDFTree(node.args[0]) if node.syscall == 'signed': return self.makeDFTree(node.args[0]) return DFIntConst('0') raise verror.FormatError("unsupported AST node type: %s %s" % (str(type(node)), str(node)))