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 _connectToIter(self, master, exclude=None, fit=False):
        # [todo] implementatino for RtlSignals of HStruct type
        if exclude and (self in exclude or master in exclude):
            return

        if self._interfaces:
            for ifc in self._interfaces:
                if exclude and ifc in exclude:
                    continue

                mIfc = getattr(master, ifc._name)
                if exclude and mIfc in exclude:
                    continue

                if mIfc._masterDir == DIRECTION.OUT:
                    if ifc._masterDir != mIfc._masterDir:
                        raise IntfLvlConfErr("Invalid connection", ifc, "<=",
                                             mIfc)

                    yield from ifc._connectTo(mIfc, exclude=exclude, fit=fit)
                else:
                    if ifc._masterDir != mIfc._masterDir:
                        raise IntfLvlConfErr("Invalid connection", mIfc, "<=",
                                             ifc)

                    yield from mIfc._connectTo(ifc, exclude=exclude, fit=fit)
        else:
            dstSig = toHVal(self)
            srcSig = toHVal(master)

            if fit:
                srcSig = fitTo(srcSig, dstSig)

            yield dstSig(srcSig)
Ejemplo n.º 3
0
    def _ternary(self, ifTrue, ifFalse):
        ifTrue = toHVal(ifTrue)
        ifFalse = toHVal(ifFalse)

        if isinstance(self, Value):
            return self._ternary__val(ifTrue, ifFalse)
        else:
            return Operator.withRes(AllOps.TERNARY, [self, ifTrue, ifFalse],
                                    ifTrue._dtype)
Ejemplo n.º 4
0
    def _connectToIter(self, master, exclude, fit):
        # [todo] implementation for RtlSignals of HStruct type
        if exclude and (self in exclude or master in exclude):
            return

        if self._interfaces:
            seen_master_intfs = []
            for ifc in self._interfaces:
                if exclude and ifc in exclude:
                    mIfc = getattr(master, ifc._name, None)
                    if mIfc is not None:
                        seen_master_intfs.append(mIfc)
                    continue

                mIfc = getattr(master, ifc._name)
                seen_master_intfs.append(mIfc)
                if exclude and mIfc in exclude:
                    continue

                if mIfc._masterDir == DIRECTION.OUT:
                    if ifc._masterDir != mIfc._masterDir:
                        raise IntfLvlConfErr("Invalid connection", ifc, "<=",
                                             mIfc)

                    yield from ifc._connectToIter(mIfc, exclude, fit)
                else:
                    if ifc._masterDir != mIfc._masterDir:
                        raise IntfLvlConfErr("Invalid connection", mIfc, "<=",
                                             ifc)

                    yield from mIfc._connectToIter(ifc, exclude, fit)

            if len(seen_master_intfs) != len(master._interfaces):
                if exclude:
                    # there is a possiblity that the master interface was excluded,
                    # but we did not see it as the interface of the same name was not present on self
                    for ifc in self._interfaces:
                        if ifc in exclude or ifc not in seen_master_intfs:
                            continue
                        else:
                            # ifc is an interface which is extra on master and is missing an equivalent on slave
                            raise InterfaceStructureErr(self, master, exclude)
                else:
                    raise InterfaceStructureErr(self, master, exclude)
        else:
            if master._interfaces:
                raise InterfaceStructureErr(self, master, exclude)

            dstSig = toHVal(self)
            srcSig = toHVal(master)

            if fit:
                srcSig = fitTo(srcSig, dstSig)

            yield dstSig(srcSig)
Ejemplo n.º 5
0
 def _ternary(self, a, b):
     if isinstance(self, HValue):
         if self:
             return a
         else:
             return b
     else:
         a = toHVal(a)
         b = toHVal(b)
         return Operator.withRes(AllOps.TERNARY, [self, a, b],
                                 a._dtype.__copy__())
Ejemplo n.º 6
0
def bitsArithOp(self, other, op):
    other = toHVal(other, self._dtype)
    assert isinstance(other._dtype, Bits), other._dtype
    if areValues(self, other):
        return bitsArithOp__val(self, other, op._evalFn)
    else:
        if self._dtype.signed is None:
            self = self._unsigned()

        resT = self._dtype
        if isinstance(other._dtype, Bits):
            t0 = self._dtype
            t1 = other._dtype
            if t0.bit_length() != t1.bit_length():
                if not t1.strict_width:
                    # resize to type of this
                    other = other._auto_cast(t1)
                    t1 = other._dtype
                    pass
                elif not t0.strict_width:
                    # resize self to type of result
                    self = self._auto_cast(t0)
                    t0 = self._dtype
                    pass
                else:
                    raise TypeError("%r %r %r" % (self, op, other))

            if t1.signed != resT.signed:
                other = other._convSign(t0.signed)
        else:
            raise TypeError("%r %r %r" % (self, op, other))

        o = Operator.withRes(op, [self, other], self._dtype)
        return o._auto_cast(resT)
Ejemplo n.º 7
0
    def __mul__(self, other):
        Bits = self._dtype.__class__
        other = toHVal(other)
        if not isinstance(other._dtype, Bits):
            raise TypeError(other)

        if areValues(self, other):
            return self._mul__val(other)
        else:
            myT = self._dtype
            if self._dtype.signed is None:
                self = self._unsigned()

            if isinstance(other._dtype, Bits):
                s = other._dtype.signed
                if s is None:
                    other = other._unsigned()
            else:
                raise TypeError("%r %r %r" % (self, AllOps.MUL, other))

            if other._dtype == INT:
                res_w = myT.bit_length() * 2
                res_sign = self._dtype.signed
            else:
                res_w = myT.bit_length() + other._dtype.bit_length()
                res_sign = self._dtype.signed or other._dtype.signed

            subResT = Bits(res_w, signed=res_sign)
            o = Operator.withRes(AllOps.MUL, [self, other], subResT)
            resT = Bits(res_w, signed=myT.signed)
            return o._auto_cast(resT)
Ejemplo n.º 8
0
    def hardcodeRomIntoProcess(cls, rom):
        """
        Due to verilog restrictions it is not posible to use array constants
        and rom memories has to be hardcoded as process
        """
        processes = []
        signals = []
        for e in rom.endpoints:
            assert isinstance(e, Operator) and e.operator == AllOps.INDEX, e
            me, index = e.operands
            assert me is rom

            # construct output of the rom
            romValSig = rom.ctx.sig(rom.name, dtype=e.result._dtype)
            romValSig.hidden = False
            signals.append(romValSig)

            # construct process which will represent content of the rom
            cases = [(toHVal(i), [romValSig(v), ])
                     for i, v in enumerate(rom.def_val.val)]
            romSwitchStm = SwitchContainer(index, cases)

            for (_, (stm,)) in cases:
                stm.parentStm = romSwitchStm

            p = HWProcess(rom.name, [romSwitchStm, ],
                          {index, }, {index, }, {romValSig, })
            processes.append(p)

            # override usage of original index operator on rom
            # to use signal generated from this process
            for _e in e.result.endpoints:
                _e._replace_input(e.result, romValSig)
        rom.hidden = True
        return processes, signals
Ejemplo n.º 9
0
def bitsBitOp(self, other, op, getVldFn, reduceCheckFn):
    """
    :attention: If other is Bool signal, convert this to bool
        (not ideal, due VHDL event operator)
    """
    other = toHVal(other)

    iamVal = isinstance(self, Value)
    otherIsVal = isinstance(other, Value)

    if iamVal and otherIsVal:
        other = other._auto_cast(self._dtype)
        return bitsBitOp__val(self, other, op, getVldFn)
    else:
        if other._dtype == BOOL:
            self = self._auto_cast(BOOL)
            return op._evalFn(self, other)
        elif self._dtype == other._dtype:
            pass
        else:
            raise TypeError("Can not apply operator %r (%r, %r)" %
                            (op, self._dtype, other._dtype))

        if otherIsVal:
            r = reduceCheckFn(self, other)
            if r is not None:
                return r

        elif iamVal:
            r = reduceCheckFn(other, self)
            if r is not None:
                return r

        return Operator.withRes(op, [self, other], self._dtype)
Ejemplo n.º 10
0
    def __call__(self, source) -> Assignment:
        """
        Create assignment to this signal

        :attention: it is not call of function it is operator of assignment
        :return: list of assignments
        """
        if isinstance(source, InterfaceBase):
            assert source._isAccessible
            source = source._sig

        if source is None:
            source = self._dtype.from_py(None)
        else:
            source = toHVal(source, suggestedType=self._dtype)
            err = False
            try:
                source = source._auto_cast(self._dtype)
            except TypeConversionErr:
                err = True
            if err:
                raise TypeConversionErr(
                    ("Can not connect %r (of type %r) to %r "
                     "(of type %r) due type incompatibility") %
                    (source, source._dtype, self, self._dtype))

        tmp = self._getIndexCascade()
        if tmp:
            mainSig, indexCascade = tmp
            self = mainSig
        else:
            indexCascade = None

        # self = self._tryMyIndexToEndpoint()
        return Assignment(source, self, indexCascade)
Ejemplo n.º 11
0
 def __floordiv__(self, other) -> "Bits3val":
     other = toHVal(other)
     if isinstance(self, Value) and isinstance(other, Value):
         return Bits3val.__floordiv__(self, other)
     else:
         return Operator.withRes(AllOps.MUL, [self, other],
                                 self._dtype.__copy__())
Ejemplo n.º 12
0
    def _ternary(self, a, b):
        if isinstance(self, HValue):
            if self:
                return a
            else:
                return b
        else:
            a = toHVal(a)
            b = toHVal(b)
            try:
                if a == b:
                    return a
            except ValidityError:
                pass

            return Operator.withRes(AllOps.TERNARY, [self, a, b],
                                    a._dtype.__copy__())
Ejemplo n.º 13
0
 def __floordiv__(self, other) -> "Bits3val":
     other = toHVal(other, suggestedType=self._dtype)
     if isinstance(self, HValue) and isinstance(other, HValue):
         return Bits3val.__floordiv__(self, other)
     else:
         if not isinstance(other._dtype, self._dtype.__class__):
             raise TypeError()
         return Operator.withRes(AllOps.DIV, [self, other],
                                 self._dtype.__copy__())
Ejemplo n.º 14
0
def intOp(self, other, op, resT, evalFn=None):
    if evalFn is None:
        evalFn = op._evalFn

    other = toHVal(other)._auto_cast(INT)
    if areValues(self, other):
        return intOp__val(self, other, resT, evalFn)
    else:
        return Operator.withRes(op, [self, other], resT)
Ejemplo n.º 15
0
def boolCmpOp(self, other, op, evalFn=None):
    other = toHVal(other)
    if evalFn is None:
        evalFn = op._evalFn

    if areValues(self, other):
        return boolCmpOp__val(self, other, op, evalFn)
    else:
        return Operator.withRes(op, [self, other._auto_cast(BOOL)], BOOL)
Ejemplo n.º 16
0
Archivo: param.py Proyecto: Ben-401/hwt
def evalParam(p):
    """
    Get value of parameter
    """
    while isinstance(p, Param):
        p = p.get()

    if isinstance(p, RtlSignalBase):
        return p.staticEval()
        # use rather param inheritance instead of param as param value
    return toHVal(p)
Ejemplo n.º 17
0
Archivo: param.py Proyecto: Ben-401/hwt
 def __init__(self, initval):
     initval = toHVal(initval)
     super(Param, self).__init__(None, None, initval._dtype, defVal=initval)
     self._val = initval
     self.replacedWith = None
     self._parent = None
     self.__isReadOnly = False
     # {unit: (ctx, name)}
     self._scopes = {}
     self._const = True
     self.hidden = False
Ejemplo n.º 18
0
    def SignalItem(cls, si, ctx, declaration=False):
        if declaration:
            ctx = ctx.forSignal(si)

            v = si.defVal
            if si.virtualOnly:
                pass
            elif si.drivers:
                pass
            elif si.endpoints or si.simSensProcs:
                if not v.vldMask:
                    raise SerializerException(
                        "Signal %s is constant and has undefined value" %
                        si.name)
            else:
                raise SerializerException(
                    "Signal %s should be declared but it is not used" %
                    si.name)

            t = si._dtype
            dimensions = []
            while isinstance(t, HArray):
                # collect array dimensions
                dimensions.append(t.size)
                t = t.elmType

            s = "%s%s %s" % (getIndent(ctx.indent), cls.HdlType(t,
                                                                ctx), si.name)
            if dimensions:
                # to make a space between name and dimensoins
                dimensions = list(
                    map(lambda x: "[%s-1:0]" % cls.asHdl(toHVal(x), ctx),
                        dimensions))
                dimensions.append("")
                s += " ".join(reversed(dimensions))

            if isinstance(v, RtlSignalBase):
                if v._const:
                    return s + " = %s" % cls.asHdl(v, ctx)
                else:
                    # default value has to be set by reset because it is only signal
                    return s
            elif isinstance(v, Value):
                if v.vldMask:
                    return s + " = %s" % cls.Value(v, ctx)
                else:
                    return s
            else:
                raise NotImplementedError(v)

        else:
            return cls.get_signal_name(si, ctx)
Ejemplo n.º 19
0
Archivo: ops.py Proyecto: saislam/hwt
    def __call__(
        self,
        source,
        dst_resolve_fn=lambda x: x._getDestinationSignalForAssignmentToThis()
    ) -> Assignment:
        """
        Create assignment to this signal

        :attention: it is not call of function it is operator of assignment
        :return: list of assignments
        """
        assert not self._const, self
        if isinstance(source, InterfaceBase):
            assert source._isAccessible, (
                source,
                "must be a Signal Interface which is accessible in current scope"
            )
            source = source._sig

        try:
            requires_type_check = False
            if source is None:
                source = self._dtype.from_py(None)
            else:
                requires_type_check = True
                source = toHVal(source, suggestedType=self._dtype)
        except Exception as e:
            # simplification of previous exception traceback
            e_simplified = copy(e)
            raise e_simplified

        if requires_type_check:
            err = False
            try:
                source = source._auto_cast(self._dtype)
            except TypeConversionErr:
                err = True
            if err:
                raise TypeConversionErr(
                    ("Can not connect %r (of type %r) to %r "
                     "(of type %r) due type incompatibility") %
                    (source, source._dtype, self, self._dtype))
        try:
            mainSig, indexCascade = self._getIndexCascade()
            mainSig = dst_resolve_fn(mainSig)
            return Assignment(source, mainSig, indexCascade)
        except Exception as e:
            # simplification of previous exception traceback
            e_simplified = copy(e)
            raise e_simplified
Ejemplo n.º 20
0
    def __mul__(self, other):
        Bits = self._dtype.__class__
        other = toHVal(other)
        if not isinstance(other._dtype, Bits):
            raise TypeError(other)

        self_is_val = isinstance(self, HValue)
        other_is_val = isinstance(other, HValue)

        if self_is_val and other_is_val:
            return Bits3val.__mul__(self, other)
        else:
            # reduce *1 and *0
            if self_is_val and self._is_full_valid():
                _s = int(self)
                if _s == 0:
                    return self._dtype.from_py(0)
                elif _s:
                    return other._auto_cast(self._dtype)

            if other_is_val and other._is_full_valid():
                _o = int(other)
                if _o == 0:
                    return self._dtype.from_py(0)
                elif _o == 1:
                    return self

            myT = self._dtype
            if self._dtype.signed is None:
                self = self._unsigned()

            if isinstance(other._dtype, Bits):
                s = other._dtype.signed
                if s is None:
                    other = other._unsigned()
            else:
                raise TypeError("%r %r %r" % (self, AllOps.MUL, other))

            if other._dtype == INT:
                res_w = myT.bit_length()
                res_sign = self._dtype.signed
                subResT = resT = myT
            else:
                res_w = max(myT.bit_length(), other._dtype.bit_length())
                res_sign = self._dtype.signed or other._dtype.signed
                subResT = Bits(res_w, signed=res_sign)
                resT = Bits(res_w, signed=myT.signed)

            o = Operator.withRes(AllOps.MUL, [self, other], subResT)
            return o._auto_cast(resT)
Ejemplo n.º 21
0
    def hardcodeRomIntoProcess(cls, rom):
        """
        Due to verilog restrictions it is not posible to use array constants
        and rom memories has to be hardcoded as process
        """
        processes = []
        signals = []
        for e in rom.endpoints:
            assert isinstance(e, Operator) and e.operator == AllOps.INDEX, e
            me, index = e.operands
            assert me is rom

            # construct output of the rom
            romValSig = rom.ctx.sig(rom.name, dtype=e.result._dtype)
            signals.append(romValSig)
            romValSig.hidden = False

            # construct process which will represent content of the rom
            cases = [(toHVal(i), [
                romValSig(v),
            ]) for i, v in enumerate(rom.defVal.val)]
            statements = [
                SwitchContainer(index, cases),
            ]

            for (_, (stm, )) in cases:
                stm.parentStm = statements[0]

            p = HWProcess(rom.name, statements, {
                index,
            }, {
                index,
            }, {
                romValSig,
            })
            processes.append(p)

            # override usage of original index operator on rom
            # to use signal generated from this process
            def replaceOrigRomIndexExpr(x):
                if x is e.result:
                    return romValSig
                else:
                    return x

            for _e in e.result.endpoints:
                _e.operands = tuple(map(replaceOrigRomIndexExpr, _e.operands))
                e.result = romValSig

        return processes, signals
Ejemplo n.º 22
0
def bitsBitOp(self, other, op, getVldFn, reduceCheckFn):
    """
    :attention: If other is Bool signal, convert this to bool
        (not ideal, due VHDL event operator)
    """
    other = toHVal(other, self._dtype)

    iamVal = isinstance(self, HValue)
    otherIsVal = isinstance(other, HValue)

    if iamVal and otherIsVal:
        other = other._auto_cast(self._dtype)
        return bitsBitOp__val(self, other, op._evalFn, getVldFn)
    else:
        s_t = self._dtype
        o_t = other._dtype
        if not isinstance(o_t, s_t.__class__):
            raise TypeError(o_t)

        if s_t == o_t:
            pass
        elif o_t == BOOL and s_t != BOOL:
            self = self._auto_cast(BOOL)
            return op._evalFn(self, other)
        elif o_t != BOOL and s_t == BOOL:
            other = other._auto_cast(BOOL)
            return op._evalFn(self, other)
        elif s_t.bit_length() == 1 and o_t.bit_length() == 1\
                and s_t.signed is o_t.signed \
                and s_t.force_vector != o_t.force_vector:
            if s_t.force_vector:
                self = self[0]
            else:
                other = other[0]
        else:
            raise TypeError("Can not apply operator %r (%r, %r)" %
                            (op, self._dtype, other._dtype))

        if otherIsVal:
            r = reduceCheckFn(self, other)
            if r is not None:
                return r

        elif iamVal:
            r = reduceCheckFn(other, self)
            if r is not None:
                return r

        return Operator.withRes(op, [self, other], self._dtype)
Ejemplo n.º 23
0
def In(sigOrVal, iterable):
    """
    HDL convertible "in" operator, check if any of items
    in "iterable" equals "sigOrVal"
    """
    res = None
    for i in iterable:
        i = toHVal(i)
        if res is None:
            res = sigOrVal._eq(i)
        else:
            res = res | sigOrVal._eq(i)

    assert res is not None, "argument iterable is empty"
    return res
Ejemplo n.º 24
0
Archivo: param.py Proyecto: Ben-401/hwt
    def set(self, val):
        """
        set value of this param
        """
        assert not self.__isReadOnly, \
            ("This parameter(%s) was locked"
             " and now it can not be changed" % self.name)
        assert self.replacedWith is None, \
            ("This param was replaced with new one and this "
             "should not exists")

        val = toHVal(val)
        self.defVal = val
        self._val = val.staticEval()
        self._dtype = self._val._dtype
Ejemplo n.º 25
0
    def Case(self, caseVal, *statements):
        "c-like case of switch statement"
        assert self.parentStm is None
        caseVal = toHVal(caseVal, self.switchOn._dtype)

        assert isinstance(caseVal, HValue), caseVal
        assert caseVal._is_full_valid(), "Cmp with invalid value"
        assert caseVal not in self._case_value_index, (
            "Switch statement already has case for value ", caseVal)

        self.rank += 1
        case = []
        self._case_value_index[caseVal] = len(self.cases)
        self.cases.append((caseVal, case))
        self._register_stements(statements, case)

        return self
Ejemplo n.º 26
0
    def __call__(self, source):
        """
        assign to signal which is next value of this register

        :return: list of assignments
        """
        if isinstance(source, InterfaceBase):
            source = source._sig

        if source is None:
            source = self._dtype.from_py(None)
        else:
            source = toHVal(source)
            source = source._auto_cast(self._dtype)

        a = Assignment(source, self.next)
        return [a, ]
Ejemplo n.º 27
0
    def __getitem__(self, key):
        iamVal = isinstance(self, HValue)
        key = toHVal(key)
        isSLICE = isinstance(key, Slice.getValueCls())

        if isSLICE:
            raise NotImplementedError()
        elif isinstance(key, (HValue, RtlSignalBase)):
            pass
        else:
            raise NotImplementedError(
                f"Index operation not implemented for index {key}")

        if iamVal and isinstance(key, HValue):
            return self._getitem__val(key)

        return Operator.withRes(AllOps.INDEX, [self, key],
                                self._dtype.element_t)
Ejemplo n.º 28
0
def _connect(src, dst, exclude, fit):
    if isinstance(src, InterfaceBase):
        if isinstance(dst, InterfaceBase):
            return dst._connectTo(src, exclude=exclude, fit=fit)
        src = src._sig

    assert not exclude, "this intf. is just a signal"
    if src is None:
        src = dst._dtype.fromPy(None)
    else:
        src = toHVal(src)

    if fit:
        src = fitTo(src, dst)

    src = src._auto_cast(dst._dtype)

    return dst(src)
Ejemplo n.º 29
0
    def __getitem__(self, key):
        iamVal = isinstance(self, Value)
        key = toHVal(key)
        isSLICE = isinstance(key, Slice.getValueCls())

        if isSLICE:
            raise NotImplementedError()
        elif isinstance(key, RtlSignalBase):
            key = key._auto_cast(INT)
        elif isinstance(key, Value):
            pass
        else:
            raise NotImplementedError(
                "Index operation not implemented for index %r" % (key))

        if iamVal and isinstance(key, Value):
            return self._getitem__val(key)

        return Operator.withRes(AllOps.INDEX, [self, key], self._dtype.elmType)
Ejemplo n.º 30
0
def _connect(src, dst, exclude, fit):
    # [TODO]: support for RtlSignals of struct type + interface with same signal structure
    if isinstance(src, InterfaceBase):
        if isinstance(dst, InterfaceBase):
            return dst._connectTo(src, exclude=exclude, fit=fit)

    assert not exclude, ("dst does not contain subinterfaces,"
                         " excluded should be already processed in this state",
                         src, dst, exclude)
    if src is None:
        src = dst._dtype.from_py(None)
    else:
        src = toHVal(src)

    if fit:
        src = fitTo(src, dst)

    src = src._auto_cast(dst._dtype)

    return dst(src)