Example #1
0
    def __getitem__(self, key: Union[int, slice, "Bits3val"]) -> "Bits3val":
        "self[key]"
        if isinstance(key, slice):
            firstBitNo, size = normalize_slice(key, self._dtype.bit_length())
            val = get_bit_range(self.val, firstBitNo, size)
            vld = get_bit_range(self.vld_mask, firstBitNo, size)
        elif isinstance(key, (int, Bits3val)):
            size = 1
            try:
                _i = int(key)
            except ValidityError:
                _i = None

            if _i is None:
                val = 0
                vld = 0
            else:
                if _i < 0 or _i >= self._dtype.bit_length():
                    raise IndexError("Index out of range", _i)

                val = get_bit(self.val, _i)
                vld = get_bit(self.vld_mask, _i)
        else:
            raise TypeError(key)

        new_t = self._dtype.__class__(size, signed=self._dtype.signed)
        return new_t.from_py(val, vld)
Example #2
0
File: ram.py Project: mfkiwl/hwtLib
    def _write_single_word(self, data: HValue, strb: int, word_i: int):
        if strb == 0:
            return
        if strb != self.allMask:
            cur = self.data.get(word_i, None)
            if cur is None:
                cur_val = 0
                cur_mask = 0
            elif isinstance(cur, int):
                cur_val = cur
                cur_mask = self.allMask
            else:
                cur_val = cur.val
                cur_mask = cur.vld_mask

            for i in range(self.cellSize):
                if get_bit(strb, i):
                    cur_val = set_bit_range(
                        cur_val, i * 8, 8, get_bit_range(data.val, i * 8, 8))
                    cur_mask = set_bit_range(
                        cur_mask, i * 8, 8, get_bit_range(data.vld_mask, i * 8, 8))
            if cur_mask == self.allMask:
                data = cur_val
            else:
                data = self.word_t.from_py(cur_val, cur_mask)
        # print(f"data[{word_i:d}] = {data}")
        self.data[word_i] = data
Example #3
0
    def is_footer_mask_set_values(self, LOOK_AHEAD, regs):
        D_W = self.DATA_WIDTH
        BYTE_CNT = D_W // 8
        FOOTER_WIDTH = self.FOOTER_WIDTH
        din = self.dataIn

        if self.USE_KEEP:
            in_mask = din.keep
        elif self.USE_STRB:
            in_mask = din.strb
        elif self.DATA_WIDTH == 8:
            in_mask = BIT.from_py(1, 1)
        else:
            raise NotImplementedError(
                "keep/strb can be ignored only for DATA_WIDTH=8")

        set_is_footer = self._sig("set_is_footer")
        set_is_footer(din.valid & din.last)
        mask_cases = []
        for last_B_valid, bytes_in_last_input_word in iter_with_last(
                range(1, BYTE_CNT + 1)):
            footer_end = (LOOK_AHEAD * BYTE_CNT + bytes_in_last_input_word) * 8
            footer_start = footer_end - FOOTER_WIDTH
            assert footer_start > 0, (
                "otherwise we would not be able to send last for previous frame",
                footer_start)
            assert footer_start < D_W * 3, (
                "footer start can appear only in last-1 or last-2 regster,"
                " last register is output register", footer_start, D_W)
            _is_footer = set_bit_range(0, footer_start // 8, FOOTER_WIDTH // 8,
                                       mask(FOOTER_WIDTH // 8))
            set_flags = []
            for i, (_, _, is_footer_set_val, _, _) in enumerate(regs):
                if i == 0:
                    is_footer_val = 0
                    is_footer_val_last_word = get_bit_range(
                        _is_footer, (LOOK_AHEAD - i) * BYTE_CNT, BYTE_CNT)
                    set_flags.append(
                        If(set_is_footer,
                           is_footer_set_val(is_footer_val_last_word)).Else(
                               is_footer_set_val(is_footer_val)))
                else:
                    is_footer_val = get_bit_range(
                        _is_footer, (LOOK_AHEAD - i + 1) * BYTE_CNT, BYTE_CNT)
                    set_flags.append(is_footer_set_val(is_footer_val))

            if last_B_valid:
                # last byte also valid
                mask_default = set_flags
            else:
                # last 0 from the end of the validity mask
                mask_cases.append(
                    (~in_mask[bytes_in_last_input_word], set_flags))

        SwitchLogic(mask_cases, mask_default)
        return set_is_footer
Example #4
0
def packAxiSFrame(dataWidth, structVal, withStrb=False):
    """
    pack data of structure into words on axis interface
    """
    if withStrb:
        byte_cnt = dataWidth // 8

    words = iterBits(structVal,
                     bitsInOne=dataWidth,
                     skipPadding=False,
                     fillup=True)
    for last, d in iter_with_last(words):
        assert d._dtype.bit_length() == dataWidth, d._dtype.bit_length()
        if withStrb:
            word_mask = 0
            for B_i in range(byte_cnt):
                m = get_bit_range(d.vld_mask, B_i * 8, 8)
                if m == 0xff:
                    word_mask = set_bit(word_mask, B_i)
                else:
                    assert m == 0, ("Each byte has to be entirely valid"
                                    " or entirely invalid,"
                                    " because of mask granularity", m)
            yield (d, word_mask, last)
        else:
            yield (d, last)
Example #5
0
    def _append_frame(self, frame: List[int], add_preamble=True):
        data = self.data
        if add_preamble:
            preamble = [
                0x0,
                *[int(ETH.PREAMBLE_1B) for _ in range(7)],
                int(ETH.SFD),
            ]
            frame = chain(preamble, frame)

        for b in frame:
            b01 = b & 0b11
            b23 = get_bit_range(b, 2, 2)
            b45 = get_bit_range(b, 4, 2)
            b67 = get_bit_range(b, 6, 2)
            data.extend([b01, b23, b45, b67])
Example #6
0
    def check_r_trans(self, ar_ref, driver_r_ref):
        u = self.u

        self.assertEqual(len(u.driver._ag.req.data), 0)
        self.assertEqual(len(u.axi.r._ag.data), 0)

        r_data = []
        m_width = u.driver.r.strb._dtype.bit_length()
        for (d, m, l) in u.driver.r._ag.data:
            if l:
                m = int(m)
                invalid_seen = False
                for B_i in range(m_width):
                    B = get_bit_range(d.vld_mask, B_i * 8, 8)
                    _m = get_bit(m, B_i)
                    if _m and B != 0xff:
                        d = None
                        break
                    if invalid_seen:
                        if _m:
                            raise ValueError(
                                "The value prefix is invalid, but there is a part of the value which is valid",
                                d, B_i)
                    else:
                        if not _m:
                            invalid_seen = True

                if d is not None:
                    # mask removes the potentially invalid bytes
                    d = d.val
            r_data.append((d, m, l))

        self.assertValSequenceEqual(r_data, driver_r_ref)

        self.assertValSequenceEqual(u.axi.ar._ag.data, ar_ref)
Example #7
0
    def _impl(self) -> None:
        if len(self.MASTERS) > 1:
            raise NotImplementedError()

        m = self.s[0]

        wrack = rdack = err = BIT.from_py(0)
        AW = int(self.ADDR_WIDTH)
        rdata = []
        for i, (s, (s_offset, s_size)) in\
                enumerate(zip(self.m, self.SLAVES)):
            s.bus2ip_addr(m.bus2ip_addr, fit=True)
            s.bus2ip_be(m.bus2ip_be)
            s.bus2ip_rnw(m.bus2ip_rnw)
            s.bus2ip_data(m.bus2ip_data)

            bitsOfSubAddr = log2ceil(s_size - 1)
            prefix = get_bit_range(s_offset, bitsOfSubAddr, AW - bitsOfSubAddr)
            cs = self._sig(f"m_cs_{i:d}")
            cs(m.bus2ip_addr[AW:bitsOfSubAddr]._eq(prefix))
            s.bus2ip_cs(m.bus2ip_cs & cs)

            err = err | (cs & s.ip2bus_error)
            rdack = rdack | (cs & s.ip2bus_rdack)
            wrack = wrack | (cs & s.ip2bus_wrack)
            rdata.append((cs, s.ip2bus_data))

        m.ip2bus_error(err)
        m.ip2bus_rdack(rdack)
        m.ip2bus_wrack(wrack)

        SwitchLogic([(sel, m.ip2bus_data(data)) for sel, data in rdata],
                    default=m.ip2bus_data(None))
Example #8
0
    def getBits(self, start, end, sign):
        """
        Gets value of bits between selected range from memory

        :param start: bit address of start of bit of bits
        :param end: bit address of first bit behind bits
        :return: instance of BitsVal (derived from SimBits type)
                 which contains copy of selected bits
        """
        wordWidth = self.cellSize * 8

        inFieldOffset = 0
        allMask = mask(wordWidth)
        value = Bits(end - start, signed=sign).from_py(None)

        while start != end:
            assert start < end, (start, end)

            dataWordIndex = start // wordWidth
            v = self.data.get(dataWordIndex, None)

            endOfWord = (dataWordIndex + 1) * wordWidth
            width = min(end, endOfWord) - start
            offset = start % wordWidth
            if v is None:
                val = 0
                vld_mask = 0
            elif isinstance(v, int):
                val = get_bit_range(v, offset, width)
                vld_mask = allMask
            else:
                val = get_bit_range(v.val, offset, width)
                vld_mask = get_bit_range(v.vld_mask, offset, width)

            m = mask(width)
            value.val |= (val & m) << inFieldOffset
            value.vld_mask |= (vld_mask & m) << inFieldOffset

            inFieldOffset += width
            start += width

        return value
Example #9
0
def getBits_from_array(array,
                       wordWidth,
                       start,
                       end,
                       reinterpretElmToType=None):
    """
    Gets value of bits between selected range from memory

    :param start: bit address of start of bit of bits
    :param end: bit address of first bit behind bits
    :return: instance of BitsVal (derived from SimBits type) which contains
        copy of selected bits
    """
    inPartOffset = 0
    value = Bits(end - start, None).from_py(None)

    while start != end:
        assert start < end, (start, end)

        dataWordIndex = start // wordWidth

        v = array[dataWordIndex]
        if reinterpretElmToType is not None:
            v = v._reinterpret_cast(reinterpretElmToType)

        endOfWord = (dataWordIndex + 1) * wordWidth
        width = min(end, endOfWord) - start
        offset = start % wordWidth

        val = get_bit_range(v.val, offset, width)
        vld_mask = get_bit_range(v.vld_mask, offset, width)

        m = mask(width)
        value.val |= (val & m) << inPartOffset
        value.vld_mask |= (vld_mask & m) << inPartOffset

        inPartOffset += width
        start += width

    return value
Example #10
0
    def test_single_write(self):
        u = self.u
        d = int_list_to_int(range(u.CACHE_LINE_SIZE), 8)
        u.w._ag.data.append((1, d, mask(u.CACHE_LINE_SIZE)))
        self.runSim(10 * CLK_PERIOD)

        aw = u.m.aw._ag
        self.assertValSequenceEqual(aw.data, [
            aw.create_addr_req(addr=1 * u.CACHE_LINE_SIZE,
                               _len=u.BUS_WORDS_IN_CACHE_LINE - 1,
                               _id=0),
        ])
        self.assertValSequenceEqual(
            u.m.w._ag.data,
            [(get_bit_range(d, u.DATA_WIDTH * i,
                            u.DATA_WIDTH), mask(u.DATA_WIDTH // 8), int(last))
             for last, i in iter_with_last(range(u.BUS_WORDS_IN_CACHE_LINE))])
Example #11
0
    def packData(self, data):
        """
        Pack data into list of BitsVal of specified dataWidth

        :param data: dict of values for struct fields {fieldName: value}

        :return: list of BitsVal which are representing values of words
        """
        typeOfWord = Bits(self.wordWidth, None)
        fieldToVal = self._fieldToTPart
        if fieldToVal is None:
            fieldToVal = self._fieldToTPart = self.fieldToDataDict(
                self.origin.dtype,
                data,
                {})

        for _, transParts in self.walkWords(showPadding=True):
            # build a single data word
            actualVldMask = 0
            actualVal = 0
            for tPart in transParts:
                high, low = tPart.getBusWordBitRange()
                fhigh, flow = tPart.getFieldBitRange()
                if not tPart.isPadding:
                    val = fieldToVal.get(tPart.tmpl.origin, None)
                else:
                    val = None

                if val is None:
                    newBits = 0
                    vld = 0
                else:
                    newBits = get_bit_range(val, flow, fhigh - flow)
                    vld = mask(high - low)

                actualVal = set_bit_range(actualVal, low, high - low, newBits)
                actualVldMask = set_bit_range(actualVldMask, low, high - low, vld)

            v = typeOfWord.getValueCls()(typeOfWord, actualVal,
                                         actualVldMask)
            yield v
Example #12
0
def _axis_recieve_bytes(ag_data,
                        D_B,
                        use_keep,
                        use_id,
                        offset=0) -> Tuple[int, List[int]]:
    offset = None
    data_B = []
    last = False
    first = True
    current_id = 0
    mask_all = mask(D_B)
    while ag_data:
        _d = ag_data.popleft()
        if use_id:
            if use_keep:
                id_, data, keep, last = _d
                keep = int(keep)
            else:
                id_, data, last = _d
                keep = mask_all
            id_ = int(id_)
        else:
            if use_keep:
                data, keep, last = _d
                keep = int(keep)
            else:
                data, last = _d
                keep = mask_all
            id_ = 0

        last = int(last)
        assert keep > 0
        if offset is None:
            # first iteration
            # expecting potential 0s in keep and the rest 1
            for i in range(D_B):
                # i represents number of 0 from te beginning of of the keep
                # value
                if keep & (1 << i):
                    offset = i
                    break
            assert offset is not None, keep
        for i in range(D_B):
            if get_bit(keep, i):
                d = get_bit_range(data.val, i * 8, 8)
                if get_bit_range(data.vld_mask, i * 8, 8) != 0xff:
                    raise AssertionError(
                        "Data not valid but it should be"
                        f" based on strb/keep B_i:{i:d}, 0x{keep:x}, 0x{data.vld_mask:x}"
                    )
                data_B.append(d)

        if first:
            offset_mask = mask(offset)
            assert offset_mask & keep == 0, (offset_mask, keep)
            first = False
            current_id = id_
        elif not last:
            assert keep == mask_all, keep
        if not first:
            assert current_id == id_, ("id changed in frame beats", current_id,
                                       "->", id_)
        if last:
            break

    if not last:
        if data_B:
            raise ValueError("Unfinished frame", data_B)
        else:
            raise ValueError("No frame available")

    if use_id:
        return offset, id_, data_B
    else:
        return offset, data_B
Example #13
0
    def _impl(self) -> None:
        if len(self.MASTERS) > 1:
            raise NotImplementedError()
        m = self.s[0]
        # :note: theoretically not required
        b = Mi32Buff()
        b.ADDR_BUFF_DEPTH = 1
        b.DATA_BUFF_DEPTH = 1
        b._updateParamsFrom(self)
        self.s_0_buff = b
        b.s(m)
        m = b.m

        propagateClkRstn(self)

        r_order = self.r_data_order.dataIn
        AW = int(self.ADDR_WIDTH)
        rdata = []
        r_data_t = HStruct(
            (m.drd._dtype, "data"),
            (BIT, "vld"),
        )
        for i, (s, (s_offset, s_size)) in\
                enumerate(zip(self.m, self.SLAVES)):
            # s = Mi32()
            s.addr(m.addr, fit=True)
            s.be(m.be)

            s.dwr(m.dwr)

            bitsOfSubAddr = log2ceil(s_size - 1)
            prefix = get_bit_range(s_offset, bitsOfSubAddr, AW - bitsOfSubAddr)
            cs = self._sig(f"m_cs_{i:d}")
            cs(m.addr[AW:bitsOfSubAddr]._eq(prefix))
            s.rd(m.rd & cs & r_order.rd)
            s.wr(m.wr & cs & r_order.rd)

            # we have to add 1 read data latency because the slave index would not be ready
            # oder fifo
            r_data_tmp = self._reg(f"r_data{i:d}_tmp",
                                   r_data_t,
                                   def_val={"vld": 0})
            r_data_tmp.data(s.drd)
            r_data_tmp.vld(s.drdy)
            rdata.append((i, cs & s.ardy, r_data_tmp))

        # r_data_order feed
        SwitchLogic([(addr_en, r_order.data(i)) for i, addr_en, _ in rdata],
                    default=r_order.data(None))
        addr_ack = Or(*[x[1] for x in rdata])
        r_order.vld(addr_ack & m.rd)
        # m = Mi32()
        m.ardy(addr_ack & r_order.rd & (m.rd | m.wr))

        r_order = self.r_data_order.dataOut
        If(
            r_order.vld,
            Switch(r_order.data).add_cases(
                [(slave_i, [m.drd(data.data), m.drdy(1)])
                 for slave_i, _, data in rdata], ).Default(
                     # this case can not happen unless bug in code
                     m.drd(None),
                     m.drdy(None))).Else(
                         m.drd(None),
                         m.drdy(False),
                     )
        r_order.rd(Or(*[data.vld for _, _, data in rdata]))
Example #14
0
 def monitor(self):
     i = self.intf
     while True:
         # print(self.sim.now // Time.ns)
         yield Edge(i.en)
         yield WaitTimeslotEnd()
         if i.en.read():
             rs = int(i.rs.read())
             rw = int(i.rw.read())
             d = int(i.d.read())
             if rs == Hd44780Intf.RS_CONTROL:
                 # command processing
                 if rw == Hd44780Intf.RW_WRITE:
                     if d & 0b10000000:
                         # cursor position set (DDRAM addr)
                         d = get_bit_range(d, 0, 7)
                         self.cursor[0] = ceil(d / i.COLS)
                         assert self.cursor[0] < i.ROWS, self.cursor[0]
                         self.cursor[1] = d % i.ROWS
                     elif d & 0b01000000:
                         raise NotImplementedError()
                     elif d & 0b00100000:
                         # CMD_FUNCTION_SET
                         self.data_len = get_bit(d, 4)
                         self.lines = get_bit(d, 3)
                         self.font = get_bit(d, 2)
                     elif d & 0b00010000:
                         # CMD_CURSOR_OR_DISPLAY_SHIFT
                         shift_or_cursor = get_bit(d, 3)
                         right_left = get_bit(d, 2)
                         if shift_or_cursor == Hd44780Intf.SC_CURSOR_MOVE:
                             c = self.cursor
                             if right_left == Hd44780Intf.SHIFT_RIGHT:
                                 c[1] += 1
                                 if c[1] == i.COLS:
                                     c[1] = 0
                                     c[0] += 1
                                     if c[0] == i.ROWS:
                                         c[0] = 0
                         else:
                             raise NotImplementedError()
                     elif d & 0b00001000:
                         # CMD_DISPLAY_CONTROL
                         self.display_on = get_bit(d, 2)
                         self.cursor_on = get_bit(d, 1)
                         self.cursor_blink = get_bit(d, 0)
                     elif d & 0b00000100:
                         # CMD_ENTRY_MODE_SET
                         shift_en = get_bit(d, 0)
                         incr_decr = get_bit(d, 1)
                         if shift_en:
                             self.shift = 1 if incr_decr == Hd44780Intf.INCR else -1
                         else:
                             self.shift = 0
                     elif d & Hd44780Intf.CMD_RETURN_HOME:
                         raise NotImplementedError()
                     elif d == Hd44780Intf.CMD_CLEAR_DISPLAY:
                         for line in self.screen:
                             for x in range(i.COLS):
                                 line[x] = ' '
                         self.cursor = [0, 0]
                     else:
                         raise NotImplementedError("{0:8b}".format(d))
                 else:
                     assert rw == Hd44780Intf.RW_READ, rw
                     raise NotImplementedError()
             else:
                 # data processing
                 assert rs == Hd44780Intf.RS_DATA, rs
                 if self.data_len == Hd44780Intf.DATA_LEN_8b:
                     d = int(d)
                     d = self.REV_CHAR_MAP.get(d, " ")
                     cur = self.cursor
                     self.screen[cur[0]][cur[1]] = d
                     cur[1] += self.shift
                 else:
                     raise NotImplementedError()