Exemple #1
0
 def asQuartusTcl(self, buff, version, component, entity, allInterfaces, thisIf):
     self.quartus_tcl_add_interface(buff, thisIf)
     name = getSignalName(thisIf)
     #self.quartus_prop("associatedClock", clock)
     self.quartus_prop(buff, name, "synchronousEdges", "DEASSERT")
     self.quartus_add_interface_port(buff, getSignalName(thisIf), thisIf, "reset")
     clk = thisIf._getAssociatedClk()
     if clk is not None:
         self.quartus_prop(buff, name, "associatedClock",
                           clk._sigInside.name, escapeStr=False)
Exemple #2
0
    def _implReadyChainBreak(self, in_vld: RtlSignal, in_rd: RtlSignal,
                             in_data: List[RtlSignal], out_vld: RtlSignal,
                             out_rd: RtlSignal, prefix: str):
        """
        Two sets of registers 0. is prioritized 1. is used as a backup
        The in_rd is not combinationally connected to out_rd
        The out_vld is not combinationally connected to in_vld
        """

        occupied = [
            self._reg(f"{prefix}occupied_{i:d}", def_val=0) for i in range(2)
        ]
        reader_prio = self._reg(f"{prefix}reader_prio", def_val=0)

        consume_0 = (reader_prio._eq(0) & occupied[0]) | ~occupied[1]
        consume_1 = (reader_prio._eq(1) & occupied[1]) | ~occupied[0]

        outData = []
        for iin in in_data:
            r0 = self._reg(prefix + 'reg0_' + getSignalName(iin), iin._dtype)
            If(in_vld & ~occupied[0], r0(iin))

            r1 = self._reg(prefix + 'reg1_' + getSignalName(iin), iin._dtype)
            If(in_vld & ~occupied[1], r1(iin))

            o = self._sig(prefix + 'out_tmp_' + getSignalName(iin), iin._dtype)

            If(consume_0 & occupied[0], o(r0)).Elif(consume_1 & occupied[1],
                                                    o(r1)).Else(o(None))
            outData.append(o)

        If(
            in_vld & (~occupied[0] | ~occupied[1]),
            If(
                occupied[0],
                reader_prio(0),
            ).Elif(
                occupied[1],
                reader_prio(1),
            ))

        oc0_set = in_vld & ~occupied[0]
        oc0_clr = out_rd & occupied[0] & consume_0

        oc1_set = in_vld & occupied[0] & ~occupied[1]
        oc1_clr = out_rd & occupied[1] & consume_1

        occupied[0]((occupied[0] | oc0_set) & ~oc0_clr)
        occupied[1]((occupied[1] | oc1_set) & ~oc1_clr)

        in_rd(~occupied[0] | ~occupied[1])
        out_vld(occupied[0] | occupied[1])

        return outData
Exemple #3
0
    def vcdRegisterInterfaces(self, obj: Union[Interface, Unit],
                              parent: Optional[VcdVarWritingScope]):
        """
        Register signals from interfaces for Interface or Unit instances
        """
        if hasattr(obj, "_interfaces") and obj._interfaces:
            name = obj._name
            parent_ = self.vcdWriter if parent is None else parent

            subScope = parent_.varScope(name)
            self._obj2scope[obj] = subScope

            with subScope:
                # register all subinterfaces
                for chIntf in obj._interfaces:
                    self.vcdRegisterInterfaces(chIntf, subScope)

                if isinstance(obj, (Unit, SimModel)):
                    # register interfaces from all subunits
                    for u in obj._units:
                        self.vcdRegisterInterfaces(u, subScope)

            return subScope
        else:
            t = obj._dtype
            if isinstance(t, self.supported_type_classes):
                tName, width, formatter = vcdTypeInfoForHType(t)
                try:
                    parent.addVar(obj, getSignalName(obj), tName, width,
                                  formatter)
                except VarAlreadyRegistered:
                    pass
Exemple #4
0
    def edgeDetector(self, sig, rise=False, fall=False, last=None, initVal=0):
        """
        :param sig: signal to detect edges on
        :param rise: if True signal for rise detecting will be returned
        :param fall: if True signal for fall detecting will be returned
        :param last: last value for sig (use e.g. when you have register and it's next signal (sig=reg.next, last=reg))
            if last is None last register will be automatically generated
        :param initVal: if last is None initVal will be used as its initialization value
        :return: signals which is high on on rising/falling edge or both (specified by rise, fall parameter)
        """
        namePrefix = getSignalName(sig)
        assert rise or fall
        if last is None:
            last = self.parent._reg(namePrefix + "_edgeDetect_last",
                                    def_val=initVal)
            last(sig)

        if rise:
            riseSig = self.parent._sig(namePrefix + "_rising")
            riseSig(sig & ~last)
        if fall:
            fallSig = self.parent._sig(namePrefix + "_falling")
            fallSig(~sig & last)
        if rise and not fall:
            return riseSig
        elif not rise and fall:
            return fallSig
        else:
            return (riseSig, fallSig)
Exemple #5
0
def _walkStructIntfAndIntfMap_unpack(structIntf: Union[HObjList, StructIntf,
                                                       UnionSink, UnionSource],
                                     intfMap):
    """
    Try to unpack intfMap and apply the selection on structIntf

    :return: Optional tuple Interface, intfMap
    """
    # items are Interface/RtlSignal or (type/interface/None or list of items, name)
    if isPaddingInIntfMap(intfMap):
        return
    elif isinstance(intfMap, tuple):
        item, name = intfMap
    else:
        item = intfMap
        assert isinstance(item, (InterfaceBase, RtlSignalBase)), item
        name = getSignalName(item)

    if isinstance(item, HdlType):
        # this part of structIntf was generated from type descriptin
        # and we are re searching only for those parts which were generated
        # from Interface/RtlSignal
        return

    return getattr(structIntf, name), item
Exemple #6
0
    def timerDynamic(self,
                     periodSig,
                     enableSig=None,
                     rstSig=None) -> RtlSignal:
        """
        Same as timer, just period is signal which can be configured dynamically
        """
        if isinstance(periodSig, (tuple, list)):
            periodSig, name = periodSig
        else:
            periodSig, name = periodSig, getSignalName(periodSig)

        parentUnit = self.parent

        timer = DynamicTimerInfo(periodSig, name)
        maxVal = timer.maxVal - 1
        assert maxVal._dtype.bit_length() > 0

        r = parentUnit._reg(timer.name + "_delayCntr",
                            periodSig._dtype,
                            def_val=0)
        timer.cntrRegister = r
        tick = DynamicTimerInfo._instantiateTimerTickLogic(
            timer, periodSig, enableSig, rstSig)

        timer.tick = parentUnit._sig(timer.name + "_delayTick")
        timer.tick(tick)
        return timer.tick
Exemple #7
0
    def timerDynamic(self, periodSig, enableSig=None, rstSig=None) -> RtlSignal:
        """
        Same as timer, just period is signal which can be configured dynamically
        """
        if isinstance(periodSig, (tuple, list)):
            periodSig, name = periodSig
        else:
            periodSig, name = periodSig, getSignalName(periodSig)

        parentUnit = self.parent

        timer = DynamicTimerInfo(periodSig, name)
        maxVal = timer.maxVal - 1
        assert maxVal._dtype.bit_length() > 0

        r = parentUnit._reg(timer.name + "_delayCntr",
                            periodSig._dtype,
                            defVal=0
                            )
        timer.cntrRegister = r
        tick = DynamicTimerInfo._instantiateTimerTickLogic(timer,
                                                           periodSig,
                                                           enableSig,
                                                           rstSig)

        timer.tick = parentUnit._sig(timer.name + "_delayTick")
        timer.tick(tick)
        return timer.tick
Exemple #8
0
    def edgeDetector(self, sig, rise=False, fall=False, last=None, initVal=0):
        """
        :param sig: signal to detect edges on
        :param rise: if True signal for rise detecting will be returned
        :param fall: if True signal for fall detecting will be returned
        :param last: last value for sig (use f.e. when you have register and it's next signal (sig=reg.next, last=reg))
            if last is None last register will be automatically generated
        :param initVal: if last is None initVal will be used as its initialization value
        :return: signals which is high on on rising/falling edge or both (specified by rise, fall parameter)
        """
        namePrefix = getSignalName(sig)
        assert rise or fall
        if last is None:
            last = self.parent._reg(namePrefix + "_edgeDetect_last", defVal=initVal)
            last(sig)

        if rise:
            riseSig = self.parent._sig(namePrefix + "_rising")
            riseSig(sig & ~last)
        if fall:
            fallSig = self.parent._sig(namePrefix + "_falling")
            fallSig(~sig & last)
        if rise and not fall:
            return riseSig
        elif not rise and fall:
            return fallSig
        else:
            return (riseSig, fallSig)
Exemple #9
0
 def __init__(self,
              sig,
              in_clk_rst: Tuple[RtlSignal, RtlSignal],
              out_clk_rst: Tuple[RtlSignal, RtlSignal],
              reg_init_val,
              name_prefix: Optional[str] = None):
     """
     :param sig: data in signal
     :param in_clk_rst: tuple source clk signal, rst signal
     :param out_clk_rst: tuple destination clk signal, rst signal
     :note: rst/rst_n is automatically resolved from reset type
     :param reg_init_val: register reset value
     """
     self.path = [
         sig,
     ]
     if name_prefix is None:
         name_prefix = getSignalName(sig) + "_"
     self.name_prefix = name_prefix
     self.IN_CLK_RST = in_clk_rst
     self.OUT_CLK_RST = out_clk_rst
     self.REG_INIT_VAL = reg_init_val
     self.META_PERIOD_NS =\
         1e9 / max(in_clk_rst[0].FREQ, in_clk_rst[0].FREQ) * 0.5
     self.in_reg_cnt = 0
     self.out_reg_cnt = 0
Exemple #10
0
    def vcdRegisterRemainingSignals(self, unit: Union[Interface, Unit]):
        unitScope = self._obj2scope[unit]
        for s in unit._ctx.signals:
            if s not in self.vcdWriter._idScope:
                t = s._dtype
                if isinstance(t, self.supported_type_classes):
                    tName, width, formatter = vcdTypeInfoForHType(t)
                    unitScope.addVar(s, getSignalName(s), tName, width,
                                     formatter)

        for u in unit._units:
            self.vcdRegisterRemainingSignals(u)
Exemple #11
0
    def __init__(self, parent, srcInterface, name=None):
        """
        :param parent: unit in which will be all units created by this builder instantiated
        :param name: prefix for all instantiated units
        :param srcInterface: input clock
        """
        self.parent = parent
        self.end = srcInterface
        if name is None:
            name = "gen_" + getSignalName(srcInterface)

        self.name = name
        self.compId = 0
Exemple #12
0
    def __init__(self, parent, srcInterface, name=None):
        """
        :param parent: unit in which will be all units created by this builder instantiated
        :param name: prefix for all instantiated units
        :param srcInterface: input clock
        """
        self.parent = parent
        self.end = srcInterface
        if name is None:
            name = "gen_" + getSignalName(srcInterface)

        self.name = name
        self.compId = 0
Exemple #13
0
 def asQuartusTcl(self, buff: List[str], version: str, component: Component,
                  packager: IpPackager, thisIf: Interface):
     IntfIpMeta.asQuartusTcl(self, buff, version,
                             component, packager, thisIf)
     name = getSignalName(thisIf)
     if thisIf._direction == INTF_DIRECTION.MASTER:
         self.quartus_prop(buff, name, "readIssuingCapability", 1)
         self.quartus_prop(buff, name, "writeIssuingCapability", 1)
         self.quartus_prop(buff, name, "combinedIssuingCapability", 1)
     else:
         self.quartus_prop(buff, name, "readAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "writeAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "combinedAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "readDataReorderingDepth", 1)
         self.quartus_prop(buff, name, "bridgesToMaster", "")
Exemple #14
0
 def asQuartusTcl(self, buff: List[str], version: str, component: Component,
                  packager: IpPackager, thisIf: Interface):
     IntfIpMeta.asQuartusTcl(self, buff, version,
                             component, packager, thisIf)
     name = getSignalName(thisIf)
     if thisIf._direction == INTF_DIRECTION.MASTER:
         self.quartus_prop(buff, name, "readIssuingCapability", 1)
         self.quartus_prop(buff, name, "writeIssuingCapability", 1)
         self.quartus_prop(buff, name, "combinedIssuingCapability", 1)
     else:
         self.quartus_prop(buff, name, "readAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "writeAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "combinedAcceptanceCapability", 1)
         self.quartus_prop(buff, name, "readDataReorderingDepth", 1)
         self.quartus_prop(buff, name, "bridgesToMaster", "")
Exemple #15
0
def _HTypeFromIntfMap(intf):
    name = getSignalName(intf)
    if isinstance(intf, (RtlSignalBase, Signal)):
        dtype = intf._dtype
    elif isinstance(intf, VldSynced):
        dtype = intf.data._dtype
    elif isinstance(intf, RegCntrl):
        dtype = intf.din._dtype
    elif isinstance(intf, BramPort_withoutClk):
        dtype = Bits(int(intf.DATA_WIDTH))[2**int(intf.ADDR_WIDTH)]
    else:
        dtype, name = intf
        assert isinstance(dtype, HdlType)
        assert isinstance(name, str)

    return (dtype, name)
Exemple #16
0
    def __init__(self, parent, srcInterface, name=None, master_to_slave=True):
        """
        :param parent: unit in which will be all units created by this builder instantiated
        :param name: prefix for all instantiated units
        :param srcInterface: start of data-path
        :param master_to_slave: if True the circuit is build in natural direction
            (master to slave, input to output) othervise it is build in reverse direction
        """
        self.parent = parent
        self.lastComp = None
        self.end = srcInterface
        if name is None:
            name = "gen_" + getSignalName(srcInterface)

        self.name = name
        self.master_to_slave = master_to_slave
        self.compId = 0
Exemple #17
0
    def postpone_val(self, sig_in, clock_enables: List[RtlSignal], name_prefix=None):
        """
        Generate a register pipeline which can be used to dealy a value, the length of pipeline
        is derived from number of clock_enable signals
        """
        if isinstance(sig_in, (int, HValue)):
            return sig_in

        if name_prefix is None:
            name_prefix = getSignalName(sig_in)
        out = sig_in
        for st_i, ce in enumerate(clock_enables):
            r = self._reg(f"{name_prefix:s}_{st_i:d}", dtype=out._dtype)
            If(ce,
               r(out)
            )
            out = r
        return out
Exemple #18
0
    def _implLatencyAndDelay(self, inVld: RtlSignal, inRd: RtlSignal,
                             inData: List[RtlSignal], outVld: RtlSignal,
                             outRd: RtlSignal, prefix: str):
        """
        Create a register pipe
        """
        wordLoaded = self._reg(prefix + "wordLoaded", def_val=0)
        If(wordLoaded, wordLoaded(~outRd)).Else(wordLoaded(inVld))

        outData = []
        for iin in inData:
            r = self._reg('reg_' + getSignalName(iin), iin._dtype)
            If(~wordLoaded, r(iin))
            outData.append(r)

        inRd(~wordLoaded)
        outVld(wordLoaded)

        return outData
Exemple #19
0
    def _impl_latency(self, inVld, inRd, inData, outVld, outRd, prefix):
        """
        Create a normal handshaked register
        """
        isOccupied = self._reg(prefix + "isOccupied", def_val=0)
        regs_we = self._sig(prefix + 'reg_we')

        outData = []
        for iin in inData:
            r = self._reg(prefix + 'reg_' + getSignalName(iin), iin._dtype)

            If(regs_we, r(iin))
            outData.append(r)

        If(isOccupied, inRd(outRd), regs_we(inVld & outRd),
           If(outRd & ~inVld, isOccupied(0))).Else(inRd(1), regs_we(inVld),
                                                   isOccupied(inVld))
        outVld(isOccupied)
        return outData
Exemple #20
0
    def oversample(self,
                   sig,
                   sampleCount,
                   sampleTick,
                   rstSig=None) -> Tuple[RtlSignal, RtlSignal]:
        """
        [TODO] last sample is not sampled correctly

        :param sig: signal to oversample
        :param sampleCount: count of samples to do
        :param sampleTick: signal to enable next sample taking
        :param rstSig: rstSig signal to reset internal counter, if is None it is not used

        :return: typle (oversampled signal, oversample valid signal)
        """
        if sig._dtype != BIT:
            raise NotImplementedError()

        n = getSignalName(sig)

        sCnt = int(sampleCount)
        sampleDoneTick = self.timer((n + "_oversampleDoneTick", sampleCount),
                                    enableSig=sampleTick,
                                    rstSig=rstSig)
        oversampleCntr = self.parent._reg(f"{n:s}_oversample{sCnt:d}_cntr",
                                          Bits(
                                              log2ceil(sampleCount) + 1,
                                              False),
                                          def_val=0)

        if rstSig is None:
            rstSig = sampleDoneTick
        else:
            rstSig = rstSig | sampleDoneTick

        If(sampleDoneTick,
           oversampleCntr(0)).Elif(sampleTick & sig,
                                   oversampleCntr(oversampleCntr + 1))

        oversampled = self.parent._sig(f"{n:s}_oversampled{sCnt:d}")
        oversampled(oversampleCntr > (sampleCount // 2 - 1))
        return oversampled, sampleDoneTick
Exemple #21
0
    def quartus_tcl_add_interface(self, buff, thisIntf):
        """
        Create interface in Quartus TCL

        :return: add_interface command string
        """
        if thisIntf._direction == INTF_DIRECTION.MASTER:
            dir_ = "start"
        else:
            dir_ = "end"

        name = getSignalName(thisIntf)
        buff.extend(
            ["add_interface %s %s %s" % (name, self.get_quartus_name(), dir_)])

        self.quartus_prop(buff, name, "ENABLED", True)
        self.quartus_prop(buff, name, "EXPORT_OF", "")
        self.quartus_prop(buff, name, "PORT_NAME_MAP", "")
        self.quartus_prop(buff, name, "CMSIS_SVD_VARIABLES", "")
        self.quartus_prop(buff, name, "SVD_ADDRESS_GROUP", "")
Exemple #22
0
    def _implLatencyAndDelay(self, inVld, inRd, inData, outVld, outRd, prefix):
        wordLoaded = self._reg(prefix + "wordLoaded", defVal=0)
        If(wordLoaded,
           wordLoaded(~outRd)
        ).Else(
            wordLoaded(inVld)
        )

        outData = []
        for iin in inData:
            r = self._reg('reg_' + getSignalName(iin), iin._dtype)
            If(~wordLoaded,
               r(iin)
            )
            outData.append(r)

        inRd(~wordLoaded)
        outVld(wordLoaded)

        return outData
Exemple #23
0
    def oversample(self, sig, sampleCount, sampleTick, rstSig=None) -> Tuple[RtlSignal, RtlSignal]:
        """
        [TODO] last sample is not sampled correctly

        :param sig: signal to oversample
        :param sampleCount: count of samples to do
        :param sampleTick: signal to enable next sample taking
        :param rstSig: rstSig signal to reset internal counter, if is None it is not used

        :return: typle (oversampled signal, oversample valid signal) 
        """
        if sig._dtype != BIT:
            raise NotImplementedError()

        n = getSignalName(sig)

        sCnt = int(sampleCount)
        sampleDoneTick = self.timer((n + "_oversampleDoneTick", sampleCount),
                                    enableSig=sampleTick,
                                    rstSig=rstSig)
        oversampleCntr = self.parent._reg(n + "_oversample%d_cntr" % (sCnt),
                                          Bits(log2ceil(sampleCount) + 1, False),
                                          defVal=0)

        if rstSig is None:
            rstSig = sampleDoneTick
        else:
            rstSig = rstSig | sampleDoneTick

        If(sampleDoneTick,
            oversampleCntr(0)
        ).Elif(sampleTick & sig,
            oversampleCntr(oversampleCntr + 1)
        )

        oversampled = self.parent._sig(n + "_oversampled%d" % (sCnt))
        oversampled(oversampleCntr > (sampleCount // 2 - 1))
        return oversampled, sampleDoneTick
Exemple #24
0
    def asQuartusTcl(self, buff: List[str], version: str, component,
                     entity: Entity, allInterfaces: List[Interface],
                     thisIf: Interface):
        """
        Add interface to Quartus tcl

        :param buff: line buffer for output
        :param version: Quartus version
        :param intfName: name of top interface
        :param component: component object from ipcore generator
        :param entity: Entity instance of top unit
        :param allInterfaces: list of all interfaces of top unit
        :param thisIf: interface to add into Quartus TCL
        """
        name = getSignalName(thisIf)
        self.quartus_tcl_add_interface(buff, thisIf)
        clk = thisIf._getAssociatedClk()
        if clk is not None:
            self.quartus_prop(buff,
                              name,
                              "associatedClock",
                              clk._sigInside.name,
                              escapeStr=False)
        rst = thisIf._getAssociatedRst()
        if rst is not None:
            self.quartus_prop(buff,
                              name,
                              "associatedReset",
                              rst._sigInside.name,
                              escapeStr=False)

        m = self.get_quartus_map()
        if m:
            intfMapOrName = m
        else:
            intfMapOrName = thisIf.name
        self._asQuartusTcl(buff, version, name, component, entity,
                           allInterfaces, thisIf, intfMapOrName)
Exemple #25
0
def _walkStructIntfAndIntfMap_unpack(structIntf, intfMap):
    """
    Try to unpack intfMap and apply the selection on structIntf
    
    :return: Optional tuple Interface, intfMap
    """
    # items are Interface/RtlSignal or (type/interface/None or list of items, name)
    if isPaddingInIntfMap(intfMap):
        return
    elif isinstance(intfMap, tuple):
        item, name = intfMap
    else:
        item = intfMap
        assert isinstance(item, (InterfaceBase, RtlSignalBase)), item
        name = getSignalName(item)

    if isinstance(item, HdlType):
        # this part of structIntf was generated from type descriptin
        # and we are re searching only for those parts which were generated
        # from Interface/RtlSignal 
        return
        
    return getattr(structIntf, name), item
Exemple #26
0
 def getInterfaceLogicalName(self, intf: Interface):
     """
     :see: doc of method on parent class
     """
     return getSignalName(intf)
Exemple #27
0
    def _impl(self):
        propagateClkRstn(self)

        for intf in self._interfaces:
            if intf not in [self.clk, self.rst_n]:
                intf.vld(getattr(self.core, getSignalName(intf)))
Exemple #28
0
 def asQuartusTcl(self, buff, version, component, entity, allInterfaces, thisIf):
     self.quartus_tcl_add_interface(buff, thisIf)
     name = getSignalName(thisIf)
     self.quartus_prop(buff, name, "clockRate", 0)
     self.quartus_add_interface_port(buff, getSignalName(thisIf), thisIf, "clk")
Exemple #29
0
    def _impl(self):
        propagateClkRstn(self)

        for intf in self._interfaces:
            if intf not in [self.clk, self.rst_n]:
                intf.vld(getattr(self.core, getSignalName(intf)))