Ejemplo n.º 1
0
def slice_to_SLICE(sliceVals, width):
    """convert python slice to value of SLICE hdl type"""
    if sliceVals.step is not None:
        raise NotImplementedError()

    start = sliceVals.start
    stop = sliceVals.stop

    if sliceVals.start is None:
        start = INT.fromPy(width)
    else:
        start = toHVal(sliceVals.start)

    if sliceVals.stop is None:
        stop = INT.fromPy(0)
    else:
        stop = toHVal(sliceVals.stop)

    startIsVal = isinstance(start, Value)
    stopIsVal = isinstance(stop, Value)

    indexesAreValues = startIsVal and stopIsVal
    if indexesAreValues:
        updateTime = max(start.updateTime, stop.updateTime)
    else:
        updateTime = -1

    return Slice.getValueCls()((start, stop), SLICE, 1, updateTime)
Ejemplo n.º 2
0
 def test_int_neg(self):
     self.assertEqual(int(INT.fromPy(-10)), -10)
     self.assertEqual(int(-INT.fromPy(10)), -10)
     self.assertEqual(int(-INT.fromPy(10)), -10)
     v = -INT.fromPy(None)
     self.assertEqual(v.val, 0)
     self.assertEqual(v.vldMask, 0)
Ejemplo n.º 3
0
 def test_int_neg(self):
     self.assertEqual(int(INT.fromPy(-10)), -10)
     self.assertEqual(int(-INT.fromPy(10)), -10)
     self.assertEqual(int(-INT.fromPy(10)), -10)
     v = -INT.fromPy(None)
     self.assertEqual(v.val, 0)
     self.assertEqual(v.vldMask, 0)
Ejemplo n.º 4
0
    def test_int_to_bool(self):
        self.assertFalse(bool(INT.fromPy(0)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(1)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(-11)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(500)._auto_cast(BOOL)))

        with self.assertRaises(ValueError):
            bool(INT.fromPy(None)._auto_cast(BOOL))
Ejemplo n.º 5
0
    def test_int_to_bool(self):
        self.assertFalse(bool(INT.fromPy(0)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(1)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(-11)._auto_cast(BOOL)))
        self.assertTrue(bool(INT.fromPy(500)._auto_cast(BOOL)))

        with self.assertRaises(ValueError):
            bool(INT.fromPy(None)._auto_cast(BOOL))
Ejemplo n.º 6
0
    def test_Bits_int_autocast(self):
        uint2_t = Bits(2)
        v0 = INT.from_py(3)
        v1 = v0._auto_cast(uint2_t)
        self.assertEqual(v1._dtype, uint2_t)

        v2 = INT.from_py(10)
        with self.assertRaises(ValueError):
            v2._auto_cast(uint2_t)
Ejemplo n.º 7
0
    def serialzeValueToTCL(self, val, do_eval=False) -> Tuple[str, str, bool]:
        """
        :see: doc of method on parent class
        """
        if isinstance(val, int):
            val = INT.from_py(val)
        if do_eval:
            val = val.staticEval()

        buff = StringIO()
        to_hdl = ToHdlAstVivadoTclExpr()
        ser = Vhdl2008Serializer.TO_HDL(buff)

        hdl = to_hdl.as_hdl(val)
        ser.visit_iHdlObj(hdl)
        tclVal = buff.getvalue()

        if isinstance(val, RtlSignalBase):
            buff = StringIO()
            hdl = to_hdl.as_hdl(val.staticEval())
            ser = Vhdl2008Serializer.TO_HDL(buff)
            ser.visit_iHdlObj(hdl)
            tclValVal = buff.getvalue()

            return tclVal, tclValVal, False
        else:
            return tclVal, tclVal, True
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
    def __setitem__(self, index, value):
        """
        this []= operator can not be called in desing description, it can be only used to update HValues
        """
        if not isinstance(self, HValue):
            raise TypeError(
                "To assign a member of hdl arrray/vector/list/... use a[index](val) instead of a[index] = val"
            )

        # convert index to hSlice or hInt
        if isinstance(index, HValue):
            index = index
        elif isinstance(index, slice):
            length = self._dtype.bit_length()
            index = slice_to_SLICE(index, length)
            if not index._is_full_valid():
                raise ValueError("invalid index", index)
        else:
            index = INT.from_py(index)

        # convert value to bits of length specified by index
        if index._dtype == SLICE:
            Bits = self._dtype.__class__
            itemT = Bits(index._size())
        else:
            itemT = BIT

        if isinstance(value, HValue):
            value = value._auto_cast(itemT)
        else:
            value = itemT.from_py(value)

        return Bits3val.__setitem__(self, index, value)
Ejemplo n.º 10
0
 def __lt__(self, other):
     if self.val.step != other.val.step:
         raise ValueError()
     if isinstance(other, INT.getValueCls()):
         return self.val.start < other
     else:
         return (self.val.start, self.val.stop) < (other.val.start,
                                                   other.val.stop)
Ejemplo n.º 11
0
 def getVectorFromType(self, dtype) -> Union[bool, None, Tuple[int, int]]:
     """
     :see: doc of method on parent class
     """
     if dtype == BIT:
         return False
     elif isinstance(dtype, Bits):
         return [dtype.bit_length() - 1, INT.from_py(0)]
Ejemplo n.º 12
0
def slice_member_to_hval(v):
    if isinstance(v, RtlSignalBase):  # is signal
        assert isinstance(v._dtype, Bits)
        return v
    elif isinstance(v, HValue):
        if isinstance(v, Bits):
            return v
        else:
            return v._auto_cast(INT)
    else:
        return INT.from_py(v)
Ejemplo n.º 13
0
def convertBits__val(self, val, toType):
    if isinstance(toType, HBool):
        return val._eq(self.getValueCls().fromPy(1, self))
    elif isinstance(toType, Bits):
        return val._convSign__val(toType.signed)
    elif toType == INT:
        return INT.getValueCls()(val.val,
                                 INT,
                                 int(val._isFullVld()),
                                 val.updateTime)

    return default_auto_cast_fn(self, val, toType)
Ejemplo n.º 14
0
 def _config(self):
     self.PARAM_0 = Param(0)
     self.PARAM_10 = Param(10)
     try:
         self.PARAM_1_sll_512 = Param(INT.from_py(1 << 512))
         raise AssertionError(
             "Parameter with int value which is"
             "too big to fit in integer type of target hdl language")
     except ValueError:
         # portable type for large int, generally int in verilog/vhdl is 32b wide
         self.PARAM_1_sll_512 = Param(Bits(512 + 1).from_py(1 << 512))
         self.PARAM_1_sll_512_py_int = Param(1 << 512)
Ejemplo n.º 15
0
def convertSimBits__val(self, sigOrVal, toType):
    if toType == INT or toType == SIM_INT:
        if self.signed:
            raise NotImplementedError()
        else:
            fullMask = self._allMask
            return INT.getValueCls()(sigOrVal.val, INT,
                                     sigOrVal.vldMask == fullMask,
                                     sigOrVal.updateTime)

    # other conversions should be akreadt done
    return default_auto_cast_fn(self, sigOrVal, toType)
Ejemplo n.º 16
0
    def __setitem__(self, index, value):
        """
        Only syntax sugar for user, not used inside HWT

        * Not used in HW design (__getitem__ and overloaded call operator is used instead for item assigning)
        * In simulator _setitem__val is used directly
        """
        if isinstance(index, int):
            index = INT.from_py(index)
        else:
            assert isinstance(self, HValue)
            assert isinstance(index._dtype, Bits), index._dtype

        if not isinstance(value, HValue):
            value = self._dtype.element_t.from_py(value)
        else:
            assert value._dtype == self._dtype.element_t, (
                value._dtype, self._dtype.element_t)

        return self._setitem__val(index, value)
Ejemplo n.º 17
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)

        if self.bit_length() != toType.bit_length():
            if self.strict_width:
                raise TypeConversionErr(self, toType)
            val = toType.from_py(val.val, val.vld_mask & toType.all_mask())
        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)
Ejemplo n.º 18
0
    def __setitem__(self, index, value):
        """
        Only syntax sugar for user, not used inside HWT

        * In HW design is not used (__getitem__ returns "reference"
            and it is used)

        * In simulator is used _setitem__val directly
        """
        if isinstance(index, int):
            index = INT.from_py(index)
        else:
            assert isinstance(self, HValue)
            assert isinstance(index._dtype, Bits), index._dtype

        if not isinstance(value, HValue):
            value = self._dtype.element_t.from_py(value)
        else:
            assert value._dtype == self._dtype.element_t, (
                value._dtype, self._dtype.element_t)

        return self._setitem__val(index, value)
Ejemplo n.º 19
0
def hInt(pyVal):
    """ create hdl integer value (for example integer value in vhdl)"""
    return INT.fromPy(pyVal)
Ejemplo n.º 20
0
 def test_bits_mul(self):
     n = RtlNetlist()
     s = n.sig("s", Bits(16))
     s * 10
     s * s
     self.assertEqual(int(INT.from_py(10) * INT.from_py(11)), 10 * 11)
Ejemplo n.º 21
0
def hInt(v):
    return INT.from_py(v)
Ejemplo n.º 22
0
    def _injectParametersIntoPortTypes(
            self, port_type_variants: List[Tuple[HdlPortItem,
                                                 Dict[Tuple[Param, HValue],
                                                      List[HdlType]]]],
            param_signals: List[RtlSignal]):
        updated_type_ids = set()
        param_sig_by_name = {p.name: p for p in param_signals}
        param_value_domain = {}
        for parent_port, param_val_to_t in port_type_variants:
            for (param, param_value), port_types in param_val_to_t.items():
                param_value_domain.setdefault(param, set()).add(param_value)

        for parent_port, param_val_to_t in port_type_variants:
            if id(parent_port._dtype) in updated_type_ids:
                continue
            # check which unique parameter values affects the type of the port
            # if the type changes with any parameter value integrate it in to type of the port
            # print(parent_port, param_val_to_t)
            type_to_param_values = {}
            for (param, param_value), port_types in param_val_to_t.items():
                for pt in port_types:
                    cond = type_to_param_values.setdefault(pt, UniqList())
                    cond.append((param, param_value))

            assert type_to_param_values, parent_port
            if len(type_to_param_values) == 1:
                continue  # type does not change

            # Param: values
            params_used = {}
            for t, param_values in type_to_param_values.items():
                for (param, param_val) in param_values:
                    params_used.setdefault(param, set()).add(param_val)

                # filter out parameters which are not part of type specification process
                for p, p_vals in list(params_used.items()):
                    if len(param_value_domain[p]) == len(p_vals):
                        params_used.pop(p)
                # reset sets used to check parameter values
                for p, p_vals in params_used.items():
                    p_vals.clear()

            if not params_used:
                raise AssertionError(
                    parent_port,
                    "Type changes between the variants but it does not depend on parameter",
                    param_val_to_t)

            if len(params_used) == 1 and list(
                    params_used.keys())[0].get_hdl_type() == INT:
                # try to extract param * x + y
                p_val_to_port_w = {}
                for t, param_values in type_to_param_values.items():
                    for (param, param_val) in param_values:
                        if param not in params_used:
                            continue
                        assert param_val not in p_val_to_port_w or p_val_to_port_w[
                            param_val] == t.bit_length(), parent_port
                        p_val_to_port_w[param_val] = t.bit_length()
                # t_width = n*p + c
                _p_val_to_port_w = sorted(p_val_to_port_w.items())
                t_width0, p0 = _p_val_to_port_w[0]
                t_width1, p1 = _p_val_to_port_w[1]
                # 0 == t_width0 - n*p0 + c
                # 0 == t_width1 - n*p1 + c

                # 0 == t_width0 - n*p0 - c + t_width1 - n*p1 - c
                # 0 == t_width0 + t_width1 - n*(p0 + p1) - 2c
                # c == (t_width0 + t_width1 - n*(p0 + p1) ) //2
                # n has to be int, 0 < n <= t_width0/p0
                # n is something like base size of port which is multipled by parameter
                # we searching n for which we can resolve c
                found_nc = None
                for n in range(1, t_width0 // p0 + 1):
                    c = (t_width0 + t_width1 - n * (p0 + p1)) // 2
                    if t_width0 - n * p0 + c == 0 and t_width1 - n * p1 + c == 0:
                        found_nc = (n, c)
                        break

                if found_nc is None:
                    raise NotImplementedError()
                else:
                    p = list(params_used.keys())[0]
                    p = param_sig_by_name[p._name]
                    (n, c) = found_nc
                    t = parent_port._dtype
                    t._bit_length = INT.from_py(n) * p + c
                    t._bit_length._const = True
                    updated_type_ids.add(id(t))
            else:
                condition_and_type_width = []
                default_width = None
                for t, p_vals in sorted(type_to_param_values.items(),
                                        key=lambda x: x[0].bit_length()):
                    cond = And(*(param_sig_by_name[p.hdl_name]._eq(p_val)
                                 for p, p_val in p_vals if p in params_used))
                    w = t.bit_length()
                    if default_width is None:
                        default_width = w
                    condition_and_type_width.append((cond, w))

                t = parent_port._dtype
                t._bit_length = reduce_ternary(condition_and_type_width,
                                               default_width)
                t._bit_length._const = True
                updated_type_ids.add(id(t))