Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
    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()