Пример #1
0
def makeTestbenchTemplate(unit: Unit, name: str=None):
    """
    :param unit: synthesized unit
    :return: (entity, arch, context) of testbench
    """
    if name is None:
        name = unit._name + "_tb"

    entity = Entity(name)
    arch = Architecture(entity)

    arch.components.append(unit._entity)
    arch.componentInstances.append(unit._entity)

    nl = RtlNetlist()
    ctx = {}
    for p in unit._entity.ports:
        t = p._dtype
        if isinstance(t, Bits) and not t == BIT:
            t = Bits(t.bit_length(), signed=t.signed,
                     forceVector=t.forceVector)
        s = RtlSignal(nl, p.name, t, t.fromPy(0))
        ctx[p._interface] = s
        p.connectSig(s)

    arch.variables.extend(ctx.values())

    return entity, arch, ctx
Пример #2
0
 def createTmpVarFn(suggestedName, dtype):
     s = RtlSignal(None, None, dtype, virtual_only=True)
     s.name = childCtx.scope.checkedName(suggestedName, s)
     s.hidden = False
     serializedS = cls.SignalItem(s, childCtx, declaration=True)
     extraVars.append(s)
     extraVarsSerialized.append(serializedS)
     return s
Пример #3
0
 def __init__(self, ctx, name, var_type, defaultVal=None):
     """
     :param ctx: context in which is sig. created (instance of RtlNetlist)
     :param name: suggested name
     :param var_type: type of signal
     :param defaultVal: default value for signal (used as def. val in hdl and for reset)
     """
     super().__init__(ctx, name, var_type, defaultVal)
     self.next = RtlSignal(ctx, name + "_next", var_type, nopVal=self, useNopVal=True)
Пример #4
0
    def sig(self,
            name,
            dtype=BIT,
            clk=None,
            syncRst=None,
            def_val=None,
            nop_val=NO_NOPVAL) -> Union[RtlSignal, RtlSyncSignal]:
        """
        Create new signal in this context

        :param clk: clk signal, if specified signal is synthesized
            as SyncSignal
        :param syncRst: synchronous reset signal
        :param def_val: a default value used for reset and intialization
        :param nop_val: a value which is used to drive the signal if there is no other drive
            (used to prevent latches and to specify default values for unconnected signals)
        """
        _def_val = self._try_cast_any_to_HdlType(def_val, dtype)
        if nop_val is not NO_NOPVAL:
            nop_val = self._try_cast_any_to_HdlType(nop_val, dtype)

        if clk is not None:
            s = RtlSyncSignal(self, name, dtype, _def_val, nop_val)
            if syncRst is not None and def_val is None:
                raise SigLvlConfErr(
                    "Probably forgotten default value on sync signal %s", name)
            # dst_resolve_fn is overriden because default assign would assign to the "next" signal
            if syncRst is not None:
                r = If(syncRst._isOn(), s(_def_val,
                                          dst_resolve_fn=lambda x: x)).Else(
                                              s(s.next,
                                                dst_resolve_fn=lambda x: x))
            else:
                r = [s(s.next, dst_resolve_fn=lambda x: x)]

            if isinstance(clk, (InterfaceBase, RtlSignal)):
                clk_trigger = clk._onRisingEdge()
            else:
                # has to be tuple of (clk_sig, AllOps.RISING/FALLING_EDGE)
                clk, clk_edge = clk
                if clk_edge is AllOps.RISING_EDGE:
                    clk_trigger = clk._onRisingEdge()
                elif clk_edge is AllOps.FALLING_EDGE:
                    clk_trigger = clk._onRisingEdge()
                else:
                    raise ValueError("Invalid clock edge specification",
                                     clk_edge)

            If(clk_trigger, r)
        else:
            if syncRst:
                raise SigLvlConfErr("Signal %s has reset but has no clk" %
                                    name)
            s = RtlSignal(self, name, dtype, def_val=_def_val, nop_val=nop_val)

        return s
Пример #5
0
    def withRes(opDef, operands, resT):
        """
        Create operator with result signal

        :ivar ~.resT: data type of result signal
        :ivar ~.outputs: iterable of signals which are outputs
            from this operator
        """
        # try return existing operator result
        for i, o in enumerate(operands):
            if isinstance(o, RtlSignalBase):
                if i == 0:
                    k = (opDef, i, *operands[1:])
                else:
                    k = (opDef, i, *operands[:i], *operands[i + 1:])
                try:
                    return o._usedOps[k]
                except KeyError:
                    pass
                break

        # instanciate new Operator
        op = Operator(opDef, operands)
        out = RtlSignal(getCtxFromOps(operands), None, resT)
        out._const = arr_all(op.operands, isConst)
        out.drivers.append(op)
        out.origin = op
        op.result = out

        # Register potential signals to drivers/endpoints
        first_signal = True
        for i, o in enumerate(op.operands):
            if isinstance(o, RtlSignalBase):
                o.endpoints.append(op)
                if first_signal:
                    # register operator in _usedOps operator cache
                    if i == 0:
                        k = (opDef, i, *operands[1:])
                    else:
                        k = (opDef, i, *operands[:i], *operands[i + 1:])
                    o._usedOps[k] = out
                    o._usedOpsAlias[k] = {
                        k,
                    }
                    first_signal = False
            elif isinstance(o, HValue):
                pass
            else:
                raise NotImplementedError("Operator operands can be"
                                          " only signal or values got:%r" %
                                          (o))

        if out._const:
            out.staticEval()
        return out
Пример #6
0
    def test_BitsIndexTypes(self):
        t = Bits(8)
        v = t.fromPy(1)
        with self.assertRaises(TypeError):
            v[object()]
        with self.assertRaises(IndexError):
            v[9:]
        with self.assertRaises(IndexError):
            v[:-1]

        p = Param(2)
        self.assertIsInstance(v[p], RtlSignalBase)
        self.assertEqual(v[p]._dtype.bit_length(), 1)

        p2 = p._downto(0)
        self.assertIsInstance(v[p2], RtlSignalBase)
        self.assertEqual(v[p2]._dtype.bit_length(), 2)

        p3 = Param("abc")
        with self.assertRaises(TypeError):
            v[p3]

        a = RtlSignal(None, "a", BIT)
        a._const = False
        with self.assertRaises(TypeError):
            v[p] = a

        with self.assertRaises(TypeError):
            v[a] = p

        v[p] = 1
        self.assertEqual(v, 5)

        v[p2] = 2
        self.assertEqual(v, 6)

        with self.assertRaises(TypeError):
            v[hInt(None)] = 2

        v[:] = 0
        self.assertEqual(v, 0)

        v[2] = 1
        self.assertEqual(v, 4)
        v[3:] = p
        self.assertEqual(v, 2)

        v._setitem__val(hInt(None), hInt(1))
        with self.assertRaises(ValueError):
            int(v)

        with self.assertRaises(TypeError):
            v[hStr("asfs")]
Пример #7
0
    def withRes(opDef, operands, resT, outputs=[]):
        """
        Create operator with result signal
        """
        op = Operator(opDef, operands)
        out = RtlSignal(getCtxFromOps(operands), None, resT)
        out.drivers.append(op)
        out.origin = op
        op.result = out
        op.registerSignals(outputs)

        return out
Пример #8
0
    def sig(self,
            name,
            dtype=BIT,
            clk=None,
            syncRst=None,
            def_val=None,
            nop_val=NO_NOPVAL) -> Union[RtlSignal, RtlSyncSignal]:
        """
        Create new signal in this context

        :param clk: clk signal, if specified signal is synthesized
            as SyncSignal
        :param syncRst: synchronous reset signal
        :param def_val: default value used for reset and intialization
        :param nop_val: value used a a driver if signal is not driven by any driver
        """
        _def_val = self._try_cast_any_to_HdlType(def_val, dtype)
        if nop_val is not NO_NOPVAL:
            nop_val = self._try_cast_any_to_HdlType(nop_val, dtype)

        if clk is not None:
            s = RtlSyncSignal(self, name, dtype, _def_val, nop_val)
            if syncRst is not None and def_val is None:
                raise SigLvlConfErr(
                    "Probably forgotten default value on sync signal %s", name)
            if syncRst is not None:
                r = If(syncRst._isOn(), RtlSignal.__call__(s, _def_val)).Else(
                    RtlSignal.__call__(s, s.next))
            else:
                r = [RtlSignal.__call__(s, s.next)]

            if isinstance(clk, (InterfaceBase, RtlSignal)):
                clk_trigger = clk._onRisingEdge()
            else:
                # has to be tuple of (clk_sig, AllOps.RISING/FALLING_EDGE)
                clk, clk_edge = clk
                if clk_edge is AllOps.RISING_EDGE:
                    clk_trigger = clk._onRisingEdge()
                elif clk_edge is AllOps.FALLING_EDGE:
                    clk_trigger = clk._onRisingEdge()
                else:
                    raise ValueError("Invalid clock edge specification",
                                     clk_edge)

            If(clk_trigger, r)
        else:
            if syncRst:
                raise SigLvlConfErr("Signal %s has reset but has no clk" %
                                    name)
            s = RtlSignal(self, name, dtype, def_val=_def_val, nop_val=nop_val)

        return s
Пример #9
0
 def __init__(self, ctx, name, var_type, def_val=None, nop_val=NO_NOPVAL):
     """
     :param ~.ctx: context in which is sig. created (instance of RtlNetlist)
     :param ~.name: suggested name
     :param ~.var_type: type of signal
     :param ~.def_val: default value for signal
         (used as def. val in hdl and for reset)
     """
     super().__init__(ctx, name, var_type, def_val)
     if nop_val is NO_NOPVAL:
         nop_val = self
     self.next = RtlSignal(ctx, name + "_next", var_type,
                           nop_val=nop_val)
Пример #10
0
        def createTmpVarInCurrentBlock(suggestedName, dtype,
                                       const=False, def_val=None):
            # create a new tmp variable in current process
            s = RtlSignal(None, None, dtype, virtual_only=True)
            s.name = self.name_scope.checked_name(suggestedName, s)
            s.hidden = False
            s._const = const
            if def_val is not None:
                s.def_val = def_val
                s._set_def_val()

            as_hdl = self.as_hdl_SignalItem(s, declaration=True)
            extraVars.append(s)
            extraVarsHdl.append(as_hdl)
            return s
Пример #11
0
    def sig(self, name, dtype=BIT, clk=None, syncRst=None, def_val=None):
        """
        Create new signal in this context

        :param clk: clk signal, if specified signal is synthesized
            as SyncSignal
        :param syncRst: synchronous reset signal
        """
        if isinstance(def_val, RtlSignal):
            assert def_val._const, \
                "Initial value of register has to be constant"
            _def_val = def_val._auto_cast(dtype)
        elif isinstance(def_val, Value):
            _def_val = def_val._auto_cast(dtype)
        elif isinstance(def_val, InterfaceBase):
            _def_val = def_val._sig
        else:
            _def_val = dtype.from_py(def_val)

        if clk is not None:
            s = RtlSyncSignal(self, name, dtype, _def_val)
            if syncRst is not None and def_val is None:
                raise SigLvlConfErr(
                    "Probably forgotten default value on sync signal %s", name)
            if syncRst is not None:
                r = If(syncRst._isOn(),
                       RtlSignal.__call__(s, _def_val)
                       ).Else(
                    RtlSignal.__call__(s, s.next)
                )
            else:
                r = [RtlSignal.__call__(s, s.next)]

            If(clk._onRisingEdge(),
               r
               )
        else:
            if syncRst:
                raise SigLvlConfErr(
                    "Signal %s has reset but has no clk" % name)
            s = RtlSignal(self, name, dtype, def_val=_def_val)

        self.signals.add(s)

        return s
Пример #12
0
    def withRes(opDef, operands, resT, outputs=[]):
        """
        Create operator with result signal

        :ivar resT: data type of result signal
        :ivar outputs: iterable of singnals which are outputs
            from this operator
        """
        op = Operator(opDef, operands)
        out = RtlSignal(getCtxFromOps(operands), None, resT)
        out._const = arr_all(op.operands, isConst)
        out.drivers.append(op)
        out.origin = op
        op.result = out
        op.registerSignals(outputs)
        if out._const:
            out.staticEval()
        return out
Пример #13
0
    def create_var(self,
                   suggestedName: str,
                   dtype: HdlType,
                   const=False,
                   def_val: Optional[Union[RtlSignalBase, HValue]] = None,
                   postponed_init=False) -> RtlSignal:
        # create a new tmp variable in current process
        s = RtlSignal(None, None, dtype, virtual_only=True)
        s.name = self.name_scope.checked_name(suggestedName, s)
        s.hidden = False
        s._const = const

        if def_val is not None:
            s.def_val = def_val
            if not (isinstance(def_val, RtlSignalBase) and not def_val._const):
                s._set_def_val()

        if not postponed_init:
            self.finish_var_init(s)

        return s
Пример #14
0
    def sig(self, name, typ=BIT, clk=None, syncRst=None, defVal=None):
        """
        generate new signal in context

        :param clk: clk signal, if specified signal is synthesized as SyncSignal
        :param syncRst: reset
        """
        if not isinstance(defVal, (Value, RtlSignal, InterfaceBase)):
            if isinstance(defVal, (InterfaceBase)):
                _defVal = defVal._sig
            else:
                _defVal = typ.fromPy(defVal)
        else:
            _defVal = defVal._convert(typ)

        if clk is not None:
            s = RtlSyncSignal(self, name, typ, _defVal)
            if syncRst is not None and defVal is None:
                raise Exception(
                    "Probably forgotten default value on sync signal %s", name)
            if syncRst is not None:
                r = If(syncRst._isOn(), [RtlSignal.__pow__(s, _defVal)]).Else(
                    [RtlSignal.__pow__(s, s.next)])
            else:
                r = [RtlSignal.__pow__(s, s.next)]

            If(clk._onRisingEdge(), r)
        else:
            if syncRst:
                raise SigLvlConfErr("Signal %s has reset but has no clk" %
                                    name)
            s = RtlSignal(self, name, typ, defaultVal=_defVal)

        self.signals.add(s)

        return s