예제 #1
0
파일: ram.py 프로젝트: 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
예제 #2
0
def convertBits__val(self: Bits, val: "BitVal", toType: HdlType):
    if toType == BOOL:
        return val != self.getValueCls().from_py(self, 0)
    elif isinstance(toType, Bits):
        if self.signed != toType.signed:
            if self.strict_sign and bool(self.signed) != bool(toType.signed):
                raise TypeConversionErr(self, toType)
            val = val._convSign__val(toType.signed)

        w_from, w_to = self.bit_length(), toType.bit_length()
        if w_from != w_to:
            if self.strict_width:
                raise TypeConversionErr(self, toType)
            if w_from > w_to:
                # cut off some bits from value
                new_m = val.vld_mask & toType.all_mask()
            else:
                # w_from < w_to, extend the value to some bit length
                extra_mask_bits = mask(w_to - w_from)
                new_m = set_bit_range(val.vld_mask, w_from, w_to - w_from,
                                      extra_mask_bits)
            val = toType.from_py(val.val, new_m)

        if val._dtype != toType:
            # sign and width checked, only name, strict_* flags can be different
            val = toType.from_py(val.val, val.vld_mask)
        return val
    elif toType == INT:
        return INT.getValueCls()(INT, val.val, int(val._is_full_valid()))

    return default_auto_cast_fn(self, val, toType)
예제 #3
0
    def test_mergable2(self, N=10, ADDRESSES=[
        0,
    ], randomized=False):
        """
        same as test_mergable just the inner cycle is reversed
        """
        u = self.u
        mem = AxiSimRam(u.m)
        expected = {}
        for i in range(N):
            offset = i * N
            for a in ADDRESSES:
                B_i = (i % 4)
                _i = ((offset + i) % 0xff)
                d = _i << (B_i * 8)
                m = 1 << B_i
                u.w._ag.data.append((a, d, m))
                v = expected.get(a, 0)
                v = set_bit_range(v, B_i * 8, 8, _i)
                expected[a] = v

        if randomized:
            self.randomize_all()

        self.runSim((N * len(ADDRESSES) + 10) * 3 * u.BUS_WORDS_IN_CACHE_LINE *
                    CLK_PERIOD)
        for a in ADDRESSES:
            self.assertValEqual(mem.data[a], expected[a],
                                "%d: 0x%08x" % (a, expected[a]))
예제 #4
0
    def test_mergable(self, N=10, ADDRESSES=[
        0,
    ], randomized=False):
        u = self.u
        mem = AxiSimRam(u.m)
        expected = {}
        for a in ADDRESSES:
            for i in range(N):
                B_i = i % (u.CACHE_LINE_SIZE)
                d = i << (B_i * 8)
                m = 1 << B_i
                u.w._ag.data.append((a, d, m))
                v = expected.get(a, 0)
                v = set_bit_range(v, B_i * 8, 8, i)
                expected[a] = v

        t = (N * len(ADDRESSES) + 10) * 3 * \
            u.BUS_WORDS_IN_CACHE_LINE * CLK_PERIOD
        if randomized:
            #t *= 2
            self.randomize_all()

        self.runSim(t)
        data = mem.getArray(0, u.CACHE_LINE_SIZE, max(ADDRESSES) + 1)
        for a in ADDRESSES:
            self.assertValEqual(
                data[a], expected[a],
                "%d: expected 0x%08x got 0x%08x, 0x%08x" %
                (a, expected[a], data[a].val, data[a].vld_mask))
예제 #5
0
    def __setitem__(self, index: Union[slice, int, "Bits3val"],
                    value: Union["Bits3val", int]):
        "An item assignment operator self[index] = value."
        if isinstance(index, slice):
            firstBitNo, size = normalize_slice(index, self._dtype.bit_length())
            if isinstance(value, Bits3val):
                v = value.val
                m = value.vld_mask
            else:
                v = value
                m = mask(size)

            self.val = set_bit_range(self.val, firstBitNo, size, v)
            self.vld_mask = set_bit_range(self.vld_mask, firstBitNo, size, m)
        else:
            if index is None:
                raise TypeError(index)
            try:
                _i = int(index)
            except ValidityError:
                _i = None

            if _i is None:
                self.val = 0
                self.vld_mask = 0
            else:
                if value is None:
                    v = 0
                    m = 0
                elif isinstance(value, Bits3val):
                    v = value.val
                    m = value.vld_mask
                else:
                    v = value
                    m = 0b1
                try:
                    index = int(index)
                except ValidityError:
                    index = None
                if index is None:
                    self.val = 0
                    self.vld_mask = 0
                else:
                    self.val = bit_set_to(self.val, index, v)
                    self.vld_mask = bit_set_to(self.vld_mask, index, m)
예제 #6
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
예제 #7
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
    def set_tag(self, addr, way):
        u = self.u
        tag, index, offset = u.parse_addr_int(addr)
        assert offset == 0, addr
        tag_t = u.tag_array.tag_record_t
        tag_t_w = tag_t.bit_length()
        v = tag_t.from_py({"tag": tag, "valid": 1})._reinterpret_cast(Bits(tag_t_w))

        cur_v = self._get_from_mems(self.TAGS, index)
        assert cur_v._is_full_valid(), (cur_v, index)
        val = set_bit_range(cur_v.val, way * tag_t_w, tag_t_w, v.val)
        self._set_to_mems(self.TAGS, index, val)

        return index
예제 #9
0
from enum import Enum
from pyMathBitPrecise.bit_utils import set_bit_range

# deassign_xyz_mux;
ARITHMETIC_MODES_DRC_deassign_xyz_mux = [
    # 0bxxx0101010
    *[set_bit_range(0b0000101010, 7, 3, i) for i in range(8)],
    0b0000000000,
    0b0000011000,
    0b0000011010,
    0b0000101000,
    0b0001000000,
    0b0001011000,
    0b0001011010,
    0b0001100000,
    0b0001100010,
    0b0001111000,
    0b0001111010,
    0b0010000000,
    0b0010011000,
    0b0010011001,
    0b0010011011,
    0b0010101000,
    0b0010101001,
    0b0010101011,
    0b0010101110,
    0b0011000000,
    0b0011011000,
    0b0011011001,
    0b0011011011,
    0b0011100000,