def __init__(self, value, *, width=None, signed=None): if not isinstance(value, int): raise TypeError("Value must be an integer, not {!r}".format(value)) self._value = value if width is None: width = bits_for(value) if not isinstance(width, int): raise TypeError("Width must be an integer, not {!r}".format(width)) if width < bits_for(value): raise ValueError( "Width must be greater than or equal to the number of bits needed to" " represent {}".format(value)) self._width = width if signed is None: signed = value < 0 if not isinstance(signed, bool): raise TypeError( "Signedness must be a bool, not {!r}".format(signed)) self._signed = signed
def _compute_addr_range(self, addr, size, step=1, *, alignment, extend): if addr is not None: if not isinstance(addr, int) or addr < 0: raise ValueError( "Address must be a non-negative integer, not {!r}".format( addr)) if addr % (1 << self.alignment) != 0: raise ValueError( "Explicitly specified address {:#x} must be a multiple of " "{:#x} bytes".format(addr, 1 << alignment)) else: addr = self._align_up(self._next_addr, alignment) if not isinstance(size, int) or size < 0: raise ValueError( "Size must be a non-negative integer, not {!r}".format(size)) size = self._align_up(max(size, 1), alignment) if addr > (1 << self.addr_width) or addr + size > ( 1 << self.addr_width): if extend: self.addr_width = bits_for(addr + size) else: raise ValueError( "Address range {:#x}..{:#x} out of bounds for memory map spanning " "range {:#x}..{:#x} ({} address bits)".format( addr, addr + size, 0, 1 << self.addr_width, self.addr_width)) addr_range = range(addr, addr + size, step) overlaps = self._ranges.overlaps(addr_range) if overlaps: overlap_descrs = [] for overlap in overlaps: if id(overlap) in self._resources: _, _, resource_range = self._resources[id(overlap)] overlap_descrs.append( "resource {!r} at {:#x}..{:#x}".format( overlap, resource_range.start, resource_range.stop)) if id(overlap) in self._windows: _, window_range = self._windows[id(overlap)] overlap_descrs.append("window {!r} at {:#x}..{:#x}".format( overlap, window_range.start, window_range.stop)) raise ValueError( "Address range {:#x}..{:#x} overlaps with {}".format( addr, addr + size, ", ".join(overlap_descrs))) return addr_range
def write_port(self): port = Record([("addr", bits_for(self.depth)), ("en", 1), ("data", self.width)], name="wp") self._write_ports.append(port) return port
def __init__(self, nways, nlines, nwords, base, limit): if not isinstance(nlines, int): raise TypeError( "nlines must be an integer, not {!r}".format(nlines)) if nlines == 0 or nlines & nlines - 1: raise ValueError( "nlines must be a power of 2, not {}".format(nlines)) if nwords not in {4, 8, 16}: raise ValueError( "nwords must be 4, 8 or 16, not {!r}".format(nwords)) if nways not in {1, 2}: raise ValueError("nways must be 1 or 2, not {!r}".format(nways)) if not isinstance(base, int) or base not in range(0, 2**32): raise ValueError( "base must be an integer between {:#x} and {:#x} inclusive, not {!r}" .format(0, 2**32 - 1, base)) if limit not in range(0, 2**32): raise ValueError( "limit must be an integer between {:#x} and {:#x} inclusive, not {!r}" .format(0, 2**32 - 1, limit)) if base >= limit: raise ValueError( "limit {:#x} must be greater than base {:#x}".format( limit, base)) if (limit - base) & (limit - base) - 1: raise ValueError( "limit - base must be a power of 2, not {:#x}".format(limit - base)) if base % (limit - base): raise ValueError( "base must be a multiple of limit - base, but {:#x} is not a multiple " "of {:#x}".format(base, limit - base)) self.nways = nways self.nlines = nlines self.nwords = nwords self.base = base self.limit = limit offsetbits = log2_int(nwords) linebits = log2_int(nlines) tagbits = bits_for(limit) - linebits - offsetbits - 2 self.s1_addr = Record([("offset", offsetbits), ("line", linebits), ("tag", tagbits)]) self.s1_stall = Signal() self.s1_valid = Signal() self.s2_addr = Record.like(self.s1_addr) self.s2_re = Signal() self.s2_flush = Signal() self.s2_evict = Signal() self.s2_valid = Signal() self.bus_valid = Signal() self.bus_error = Signal() self.bus_rdata = Signal(32) self.s2_miss = Signal() self.s2_flush_ack = Signal() self.s2_rdata = Signal(32) self.bus_re = Signal() self.bus_addr = Record.like(self.s1_addr) self.bus_last = Signal()