def __init__(self, val=0, min=None, max=None, _nrbits=0): if _nrbits: self._min = 0 self._max = 2**_nrbits else: self._min = min self._max = max if max is not None and min is not None: if min >= 0: _nrbits = len(bin(max - 1)) elif max <= 1: _nrbits = len(bin(min)) else: # make sure there is a leading zero bit in positive numbers _nrbits = builtins.max(len(bin(max - 1)) + 1, len(bin(min))) if isinstance(val, integer_types): self._val = val elif isinstance(val, string_types): mval = val.replace('_', '') self._val = long(mval, 2) _nrbits = len(mval) elif isinstance(val, intbv): self._val = val._val self._min = val._min self._max = val._max _nrbits = val._nrbits else: raise TypeError("intbv constructor arg should be int or string") self._nrbits = _nrbits self._handleBounds()
def __init__(self, val=None, min=None, max=None, _nrbits=0): if _nrbits: self._min = 0 self._max = 2**_nrbits else: self._min = min self._max = max if max is not None and min is not None: if min >= 0: _nrbits = len(bin(max-1)) elif max <= 1: _nrbits = len(bin(min)) else: # make sure there is a leading zero bit in positive numbers _nrbits = maxfunc(len(bin(max-1))+1, len(bin(min))) if isinstance(val, (int, long)): self._val = val elif isinstance(val, StringType): self._val = long(val, 2) _nrbits = len(val) elif isinstance(val, intbv): self._val = val._val self._min = val._min self._max = val._max _nrbits = val._nrbits elif val is None: self._val = None # for Cosimulation and X, Z support perhaps else: raise TypeError("intbv constructor arg should be int or string") self._nrbits = _nrbits self._checkBounds()
def toVHDL(self): lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits for a in self._args: if isinstance(a, bool): w = 1 else: w = len(a) lo = hi - w if w == 1: if isinstance(a, _Signal): if a._type == bool: # isinstance(a._type , bool): <- doesn't work lines.append("%s(%s) <= %s;" % (self._name, lo, a._name)) else: lines.append("%s(%s) <= %s(0);" % (self._name, lo, a._name)) else: lines.append("%s(%s) <= '%s';" % (self._name, lo, bin(ini[lo]))) else: if isinstance(a, _Signal): lines.append("%s(%s-1 downto %s) <= %s;" % (self._name, hi, lo, a._name)) else: lines.append('%s(%s-1 downto %s) <= "%s";' % (self._name, hi, lo, bin(ini[hi:lo], w))) hi = lo return "\n".join(lines)
def __init__(self, val=0, min=None, max=None, _nrbits=0): if _nrbits: self._min = 0 self._max = 2**_nrbits else: self._min = min self._max = max if max is not None and min is not None: if min >= 0: _nrbits = len(bin(max-1)) elif max <= 1: _nrbits = len(bin(min)) else: # make sure there is a leading zero bit in positive numbers _nrbits = maxfunc(len(bin(max-1))+1, len(bin(min))) if isinstance(val, (int, long)): self._val = val elif isinstance(val, StringType): mval = val.replace('_', '') self._val = long(mval, 2) _nrbits = len(val) elif isinstance(val, intbv): self._val = val._val self._min = val._min self._max = val._max _nrbits = val._nrbits else: raise TypeError("intbv constructor arg should be int or string") self._nrbits = _nrbits self._handleBounds()
def toVerilog(self): lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits for a in self._args: if isinstance(a, bool): w = 1 else: w = len(a) lo = hi - w if w == 1: if isinstance(a, _Signal): if a._type == bool: lines.append("assign %s[%s] = %s;" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = %s[0];" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = 'b%s;" % (self._name, lo, bin(ini[lo]))) else: if isinstance(a, _Signal): lines.append("assign %s[%s-1:%s] = %s;" % (self._name, hi, lo, a._name)) else: lines.append("assign %s[%s-1:%s] = 'b%s;" % (self._name, hi, lo, bin(ini[hi:lo],w))) hi = lo return "\n".join(lines)
def toVerilog(self): lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits for a in self._args: if isinstance(a, bool): w = 1 else: w = len(a) lo = hi - w if w == 1: if isinstance(a, _Signal): if a._type == bool: lines.append("assign %s[%s] = %s;" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = %s[0];" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = 'b%s;" % (self._name, lo, bin(ini[lo]))) else: if isinstance(a, _Signal): lines.append("assign %s[%s-1:%s] = %s;" % (self._name, hi, lo, a._name)) else: lines.append("assign %s[%s-1:%s] = 'b%s;" % (self._name, hi, lo, bin(ini[hi:lo], w))) hi = lo return "\n".join(lines)
def calc_nr_bits(val): if val == 0: a = 0 nrbits = int(0) # A bit arbitrary value; I chose to use same behavior as bit_length()-function elif val < 0: a = len(bin(val)) nrbits = int(ceil(log(-val, 2)) + 1) else: a = len(bin(val)) + 1 nrbits = int(ceil(log(val + 1, 2)) + 1) return nrbits
def elements(self, targethdl): lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits if targethdl == 'VHDL': for a in self._args: if isinstance(a, bool): w = 1 elif isinstance(a, string_types): aa = a.replace('_', '') w = len(aa) elif isinstance(a, ConcatSignal): # print('ConcatSignal \'elements\':', repr(a)) w = len(a) else: w = len(a) lo = hi - w if w == 1: if isinstance(a, ConcatSignal): lines.append(' {},'.format(a.elements('VHDL'))) elif isinstance(a, _Signal): # isinstance(a._type , bool): <- doesn't work if a._type == bool: lines.append(" %s," % (a._name)) else: lines.append(" %s(0)," % (a._name)) else: lines.append(" '%s'," % bin(ini[lo])) # need ' for constant else: if isinstance(a, ConcatSignal): lines.append('{},'.format(a.elements('VHDL'))) elif isinstance(a, _Signal): if a._min < 0: lines.append(" unsigned(%s)," % (a._name)) else: lines.append(" %s," % (a._name)) else: lines.append(' "%s",' % (bin(ini[hi:lo], w))) hi = lo return ''.join(lines)[:-1] # remove last ',' else: return ('Verilog not yet ...')
def toVHDL(self): # print('ConcatSignal toVHDL', repr(self)) lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits for a in self._args: # print('ConcatSignal', repr(a)) if isinstance(a, bool): w = 1 elif isinstance(a, string_types): aa = a.replace('_', '') w = len(aa) else: w = len(a) lo = hi - w if w == 1: if isinstance(a, _Signal): # isinstance(a._type , bool): <- doesn't work if a._type == bool: lines.append(" %s(%s) <= %s;" % (self._name, lo, a._name)) else: lines.append(" %s(%s) <= %s(0);" % (self._name, lo, a._name)) else: lines.append(" %s(%s) <= '%s';" % (self._name, lo, bin(ini[lo]))) else: if isinstance(a, _Signal): if a._min < 0: lines.append( " %s(%s-1 downto %s) <= unsigned(%s);" % (self._name, hi, lo, a._name)) else: lines.append(" %s(%s-1 downto %s) <= %s;" % (self._name, hi, lo, a._name)) else: # print(repr(a)) lines.append(' %s(%s-1 downto %s) <= "%s";' % (self._name, hi, lo, bin(ini[hi:lo], w))) hi = lo return "\n".join(lines)
def enum(*names, **kwargs): # args = args encoding = kwargs.get('encoding', None) if encoding is not None and encoding not in supported_encodings: raise ValueError( "Unsupported enum encoding: %s\n Supported encodings: %s" % (encoding, supported_encodings)) codedict = {} i = 0 if encoding == "user": lnames = [] # expect tuples maxval = 0 for t in names: maxval = max(maxval, t[1]) nrbits = len(bin(maxval)) for t in names: codedict[t[0]] = t[1] lnames.append(t[0]) else: lnames = names if encoding in ("one_hot", "one_cold"): nrbits = len(names) else: # binary as default nrbits = len(bin(len(names) - 1)) for name in names: if not isinstance(name, string_types): raise TypeError() if name in codedict: raise ValueError("enum literals should be unique") if encoding == "one_hot": code = bin(1 << i, nrbits) elif encoding == "one_cold": code = bin(~(1 << i), nrbits) else: # binary as default code = bin(i, nrbits) if len(code) > nrbits: code = code[-nrbits:] codedict[name] = code i += 1 class EnumItem(EnumItemType): def __init__(self, index, name, val, type): self._index = index self._name = name self._val = val self._nrbits = type._nrbits self._nritems = type._nritems self._type = type def __hash__(self): return hash((self._type, self._index)) def __repr__(self): return self._name __str__ = __repr__ def __int__(self): # print('EnumItemType int()') return int(self._val, 2) def __hex__(self): return hex(int(self._val, 2)) def _toVerilog(self, dontcare=False): val = self._val if dontcare: if encoding == "one_hot": val = val.replace('0', '?') elif encoding == "one_cold": val = val.replace('1', '?') return "%d'b%s" % (self._nrbits, val) def _toVHDL(self): return self._name def __copy__(self): return self def __deepcopy__(self, memo=None): return self def _notImplementedCompare(self, other): raise NotImplementedError __le__ = __ge__ = __lt__ = __gt__ = _notImplementedCompare def __eq__(self, other): # other can be a signal # or an integer if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is other # elif isinstance( other, int ): # other = other.val # return int(self) is other def __ne__(self, other): if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is not other class Enum(EnumType): def __init__(self, lnames, codedict, nrbits, encoding): self.__dict__['_names'] = lnames self.__dict__['_nrbits'] = nrbits self.__dict__['_nritems'] = len(names) self.__dict__['_codedict'] = codedict self.__dict__['_encoding'] = encoding self.__dict__['_name'] = None # self._names = names # self._nrbits = nrbits # self._nritems = len(names) # self._codedict = codedict # self._encoding = encoding # self._name = None for index, name in enumerate(lnames): val = codedict[name] self.__dict__[name] = EnumItem(index, name, val, self) def __setattr__(self, attr, val): raise AttributeError("Cannot assign to enum attributes") def __len__(self): return len(self._names) def __repr__(self): return "<Enum: [{}] {}>".format(self.__dict__['_encoding'], ", ".join(names)) __str__ = __repr__ def make(self, val): pass def __eq__(self, other): if (self.__dict__['_nritems'] != other.__dict__['_nritems']) \ or (self.__dict__['_names'] != other.__dict__['_names']) \ or (self.__dict__['_nrbits'] != other.__dict__['_nrbits']) \ or (self.__dict__['_encoding'] != other.__dict__['_encoding']): return False return True def _setName(self, name): # typename = "t_enum_%s" % name typename = "e_%s" % name self.__dict__['_name'] = typename _toVHDL = __str__ def _toVHDL(self): if self._encoding == 'user': return "-- User encoded enum are not usable\n" typename = self.__dict__['_name'] vstr = " type %s is (\n\t\t" % typename vstr += ",\n\t\t".join(self._names) vstr += "\n\t\t);" if self._encoding is not None: codes = " ".join( [self._codedict[name] for name in self._names]) vstr += '\nattribute enum_encoding of %s: type is "%s";' % ( typename, codes) return vstr return Enum(lnames, codedict, nrbits, encoding)
def _printVcdVec(self): if self._val is None: print("b%s %s" % ('z' * self._nrbits, self._code), file=sim._tf) else: print("b%s %s" % (bin(self._val, self._nrbits), self._code), file=sim._tf)
def _printVcdVec(self): print >> sim._tf, "b%s %s" % (bin(self._val, self._nrbits), self._code)
def enum(*names, **kwargs): # args = args encoding = kwargs.get('encoding', None) if encoding is not None and encoding not in supported_encodings: raise ValueError( "Unsupported enum encoding: %s\n Supported encodings: %s" % (encoding, supported_encodings)) if encoding in ("one_hot", "one_cold"): nrbits = len(names) else: # binary as default nrbits = len(bin(len(names) - 1)) codedict = {} i = 0 for name in names: if not isinstance(name, string_types): raise TypeError() if name in codedict: raise ValueError("enum literals should be unique") if encoding == "one_hot": code = bin(1 << i, nrbits) elif encoding == "one_cold": code = bin(~(1 << i), nrbits) else: # binary as default code = bin(i, nrbits) if len(code) > nrbits: code = code[-nrbits:] codedict[name] = code i += 1 class EnumItem(EnumItemType): def __init__(self, index, name, val, type): self._index = index self._name = name self._val = val self._nrbits = type._nrbits self._nritems = type._nritems self._type = type def __hash__(self): return hash((self._type, self._index)) def __repr__(self): return "'{}'".format(self._name) # __str__ = __repr__ def __str__(self): return self._name def __int__(self): return int(self._val, 2) def __hex__(self): return hex(int(self._val, 2)) def _toVerilog(self, dontcare=False): val = self._val if dontcare: if encoding == "one_hot": val = val.replace('0', '?') elif encoding == "one_cold": val = val.replace('1', '?') return "%d'b%s" % (self._nrbits, val) def _toVHDL(self): return self._name def __copy__(self): return self def __deepcopy__(self, memo=None): return self def _notImplementedCompare(self, other): raise NotImplementedError __le__ = __ge__ = __lt__ = __gt__ = _notImplementedCompare def __eq__(self, other): if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is other def __ne__(self, other): if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is not other class Enum(EnumType): def __init__(self, names, codedict, nrbits, encoding): self.__dict__['_names'] = names self.__dict__['_nrbits'] = nrbits self.__dict__['_nritems'] = len(names) self.__dict__['_codedict'] = codedict self.__dict__['_encoding'] = encoding self.__dict__['_name'] = None for index, name in enumerate(names): val = codedict[name] self.__dict__[name] = EnumItem(index, name, val, self) def __setattr__(self, attr, val): raise AttributeError("Cannot assign to enum attributes") def __len__(self): return len(self._names) def __repr__(self): return 'enum({})'.format(",".join( ["'{}'".format(n) for n in self._names])) # __str__ = __repr__ def __str__(self): return "<Enum: %s>" % ", ".join(self._names) def _setName(self, name): typename = "t_enum_%s" % name self.__dict__['_name'] = typename # _toVHDL = __str__ # def _toVHDL(self): # typename = self.__dict__['_name'] # # check if a member name conflicts with a reserved VHDL keyword # # for name in self.names: # # # watch out _nameValid() will add every name to a check-list # # # which will force you to be inventive with state names ... # # # e.g. the typical 'IDLE' can only be used once # # # so let's pre-fix the enum name # # # we could have modified _nameValid() to take a default boolean argument # # _nameValid(''.join((typename, '.', name))) # # enumtypedecl = "type %s is (\n " % typename # enumtypedecl += ",\n ".join(self._names) # enumtypedecl += "\n);" # if self._encoding is not None: # codes = " ".join([self._codedict[name] for name in self._names]) # enumtypedecl += '\nattribute enum_encoding of %s: type is "%s";' % (typename, codes) # return enumtypedecl def reftype(self): typename = self.__dict__['_name'] codes = None if self._encoding is not None: codes = " ".join( [self._codedict[name] for name in self._names]) return (typename, (self._names), codes) return Enum(names, codedict, nrbits, encoding)
def toVerilog(self): lines = [] ini = intbv(self._initval)[self._nrbits:] hi = self._nrbits for a in self._args: if isinstance(a, bool): w = 1 else: w = len(a) lo = hi - w if isinstance(a, _Signal) and a._name is None: # We have seen a bug when a concat signal is created in the # following way: # # sig_list = [Signal(False) for n in range(32)] # concat_sig = ConcatSignal(*reversed(sig_list)) # # It seems that the _name attribute on the signals in sig_list # is only updated if an assignment is made to them. Otherwise # _name is left as None. We need to check for None and raise # a warning. from myhdl.conversion._misc import _error from myhdl import ToVerilogWarning if w == 1: warnings.warn("%s: %s[%s]" % (_error.UndrivenSignal, self._name, lo), category=ToVerilogWarning) else: warnings.warn("%s: %s[%s:%s]" % (_error.UndrivenSignal, self._name, hi, lo), category=ToVerilogWarning) if w == 1: if isinstance(a, _Signal) and a._name is not None: # Check that a._name is not None as None should not be # written into the converted code. If it is None then we # assume no assignment has been made to the signal # (otherwise the _name attribute would have been updated # by the _analyzeSigs function). In this situation the # signal should hold its init value (as handled in the # else branch). if a._type == bool: lines.append("assign %s[%s] = %s;" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = %s[0];" % (self._name, lo, a._name)) else: lines.append("assign %s[%s] = 'b%s;" % (self._name, lo, bin(ini[lo]))) else: if isinstance(a, _Signal) and a._name is not None: # Check that a._name is not None as None should not be # written into the converted code lines.append("assign %s[%s-1:%s] = %s;" % (self._name, hi, lo, a._name)) else: lines.append("assign %s[%s-1:%s] = 'b%s;" % (self._name, hi, lo, bin(ini[hi:lo], w))) hi = lo return "\n".join(lines)
def _printVcdVec(self): if self._val is None: print("b%s %s" % ('z'*self._nrbits, self._code), file=sim._tf) else: print("b%s %s" % (bin(self._val, self._nrbits), self._code), file=sim._tf)
def enum(*names, **kwargs): # args = args encoding = kwargs.get('encoding', None) if encoding is not None and encoding not in supported_encodings: raise ValueError("Unsupported enum encoding: %s\n Supported encodings: %s" % \ (encoding, supported_encodings)) if encoding in ("one_hot", "one_cold"): nrbits = len(names) else: # binary as default nrbits = len(bin(len(names)-1)) codedict = {} i = 0 for name in names: if not isinstance(name, string_types): raise TypeError() if name in codedict: raise ValueError("enum literals should be unique") if encoding == "one_hot": code = bin(1<<i, nrbits) elif encoding == "one_cold": code = bin(~(1<<i), nrbits) else: # binary as default code = bin(i, nrbits) if len(code) > nrbits: code = code[-nrbits:] codedict[name] = code i += 1 class EnumItem(EnumItemType): def __init__(self, index, name, val, type): self._index = index self._name = name self._val = val self._nrbits = type._nrbits self._nritems = type._nritems self._type = type def __hash__(self): return hash((self._type, self._index)) def __repr__(self): return self._name __str__ = __repr__ def __hex__(self): return hex(int(self._val, 2)) __str__ = __repr__ def _toVerilog(self, dontcare=False): val = self._val if dontcare: if encoding == "one_hot": val = val.replace('0', '?') elif encoding == "one_cold": val = val.replace('1', '?') return "%d'b%s" % (self._nrbits, val) def _toVHDL(self): return self._name def __copy__(self): return self def __deepcopy__(self, memo=None): return self def _notImplementedCompare(self, other): raise NotImplementedError __le__ = __ge__ = __lt__ = __gt__ = _notImplementedCompare def __eq__(self, other): if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is other def __ne__(self, other): if isinstance(other, _Signal): other = other._val if not isinstance(other, EnumItemType) or type(self) is not type(other): raise TypeError("Type mismatch in enum item comparison") return self is not other class Enum(EnumType): def __init__(self, names, codedict, nrbits, encoding): self.__dict__['_names'] = names self.__dict__['_nrbits'] = nrbits self.__dict__['_nritems'] = len(names) self.__dict__['_codedict'] = codedict self.__dict__['_encoding'] = encoding self.__dict__['_name'] = None for index, name in enumerate(names): val = codedict[name] self.__dict__[name] = EnumItem(index, name, val, self) def __setattr__(self, attr, val): raise AttributeError("Cannot assign to enum attributes") def __len__(self): return len(self._names) def __repr__(self): return "<Enum: %s>" % ", ".join(names) __str__ = __repr__ def _setName(self, name): typename = "t_enum_%s" % name self.__dict__['_name'] = typename _toVHDL = __str__ def _toVHDL(self): typename = self.__dict__['_name'] str = "type %s is (\n " % typename str += ",\n ".join(self._names) str += "\n);" if self._encoding is not None: codes = " ".join([self._codedict[name] for name in self._names]) str += '\nattribute enum_encoding of %s: type is "%s";' % (typename, codes) return str return Enum(names, codedict, nrbits, encoding)
def _printVcdVec(self): print("b%s %s" % (bin(self._val, self._nrbits), self._code), file=sim._tf)