def _printsig(ns, s): if s.signed: n = "signed " else: n = "" if flen(s) > 1: n += "[" + str(flen(s)-1) + ":0] " n += ns.get_name(s) return n
def _printexpr(ns, node): if isinstance(node, (int, bool)): return _printintbool(node) elif isinstance(node, Signal): return ns.get_name(node), node.signed elif isinstance(node, _Operator): arity = len(node.operands) r1, s1 = _printexpr(ns, node.operands[0]) if arity == 1: if node.op == "-": if s1: r = node.op + r1 else: r = "-$signed({1'd0, " + r1 + "})" s = True else: r = node.op + r1 s = s1 elif arity == 2: r2, s2 = _printexpr(ns, node.operands[1]) if node.op in ["+", "-", "*", "&", "^", "|"]: if s2 and not s1: r1 = "$signed({1'd0, " + r1 + "})" if s1 and not s2: r2 = "$signed({1'd0, " + r2 + "})" r = r1 + " " + node.op + " " + r2 s = s1 or s2 else: raise TypeError return "(" + r + ")", s elif isinstance(node, _Slice): # Verilog does not like us slicing non-array signals... if isinstance(node.value, Signal) \ and flen(node.value) == 1 \ and node.start == 0 and node.stop == 1: return _printexpr(ns, node.value) if node.start + 1 == node.stop: sr = "[" + str(node.start) + "]" else: sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]" r, s = _printexpr(ns, node.value) return r + sr, s elif isinstance(node, Cat): l = [_printexpr(ns, v)[0] for v in reversed(node.l)] return "{" + ", ".join(l) + "}", False elif isinstance(node, Replicate): return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False else: raise TypeError
def __getitem__(self, key): from migen.fhdl.size import flen if isinstance(key, int): if key < 0: key += flen(self) return _Slice(self, key, key+1) elif isinstance(key, slice): start = key.start or 0 stop = key.stop or flen(self) if start < 0: start += flen(self) if stop < 0: stop += flen(self) if stop > flen(self): stop = flen(self) if key.step != None: raise KeyError return _Slice(self, start, stop) else: raise KeyError