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
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
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)
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
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
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")]
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
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
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)
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
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
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
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
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