Example #1
0
    def _operand(cls, operand: Union[RtlSignal, Value], operator: OpDefinition,
                 ctx: SerializerCtx):
        try:
            isTernaryOp = operand.hidden and operand.drivers[
                0].operator == AllOps.TERNARY
        except (AttributeError, IndexError):
            isTernaryOp = False

        if isTernaryOp:
            # rewrite ternary operator as if
            o = ctx.createTmpVarFn("tmpTernary", operand._dtype)
            cond, ifTrue, ifFalse = operand.drivers[0].operands
            if_ = If(cond)
            if_.ifTrue.append(
                Assignment(ifTrue, o, virtualOnly=True, parentStm=if_))
            if_.ifFalse = []
            if_.ifFalse.append(
                Assignment(ifFalse, o, virtualOnly=True, parentStm=if_))
            if_._outputs.append(o)
            for obj in (cond, ifTrue, ifFalse):
                if isinstance(obj, RtlSignalBase):
                    if_._inputs.append(obj)
            o.drivers.append(if_)
            operand = o

        s = cls.asHdl(operand, ctx)
        if isinstance(operand, RtlSignalBase):
            try:
                o = operand.singleDriver()
                if o.operator != operator and\
                        cls.opPrecedence[o.operator] <= cls.opPrecedence[operator]:
                    return "(%s)" % s
            except Exception:
                pass
        return s
Example #2
0
File: ram.py Project: mfkiwl/hwtLib
    def mem_write(mem, port: BramPort_withoutClk):
        drive = []
        if port.HAS_BE:
            assert port.DATA_WIDTH % 8 == 0, port.DATA_WIDTH
            # we for each byte separate
            #drive.append(
            #    mem[port.addr](apply_write_with_mask(mem[port.addr], port.din, port.we))
            #)
            for b_i, be in enumerate(port.we):
                low = b_i * 8
                drive.append(
                    If(be,
                       mem[port.addr][low + 8: low](port.din[low + 8: low])
                    )
                )
        elif port.HAS_R and port.HAS_W:
            # explicit we
            drive.append(
                If(port.we,
                   mem[port.addr](port.din)
                )
            )
        else:
            # en used as we
            drive.append(mem[port.addr](port.din))

        return drive
Example #3
0
 def _impl(self):
     If(
         self.a,
         self.d(self.b),
         # this two if statements will be merged together
         If(self.b, self.e(self.c)),
         If(self.b, self.f(0))).Else(self.d(0))
Example #4
0
    def _impl_latency(self, inVld, inRd, inData, outVld, outRd, prefix):
        isOccupied = self._reg(prefix + "isOccupied", defVal=0)
        regs_we = self._sig(prefix + 'reg_we')

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

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

        If(isOccupied,
            If(outRd & ~inVld,
                isOccupied(0)
            )
        ).Else(
            If(inVld,
               isOccupied(1)
            )
        )

        If(isOccupied,
           c(outRd, inRd),
           outVld(1),
           regs_we(inVld & outRd)
        ).Else(
            inRd(1),
            outVld(0),
            regs_we(inVld)
        )
        return outData
Example #5
0
 def stashLoad(self, isIdle, stash, lookupOrigin_out):
     lookup = self.lookup
     insert = self.insert
     delete = self.delete
     If(isIdle,
         If(self.clean.vld,
            stash.vldFlag(0)
            ).Elif(delete.vld,
                   stash.key(delete.key),
                   lookupOrigin_out(ORIGIN_TYPE.DELETE),
                   stash.vldFlag(0),
                   ).Elif(insert.vld,
                          lookupOrigin_out(ORIGIN_TYPE.INSERT),
                          stash.key(insert.key),
                          stash.data(insert.data),
                          stash.vldFlag(1),
                          ).Elif(lookup.vld,
                                 lookupOrigin_out(ORIGIN_TYPE.LOOKUP),
                                 stash.key(lookup.key),
                                 )
        )
     priority = [self.clean, self.delete, self.insert, lookup]
     for i, intf in enumerate(priority):
         withLowerPrio = priority[:i]
         intf.rd(And(isIdle, *map(lambda x:~x.vld, withLowerPrio)))
Example #6
0
    def _impl(self):
        ITERATIONS = int(self.ITERATIONS)
        """
        Iterates from ITERATIONS -1 to 0 body is enabled by bodyVld and if bodyRd
        then counter is decremented for next iteration
        break causes reset of counter
        """

        counter = self._reg("counter", Bits(self.COUNTER_WIDTH), ITERATIONS - 1)

        If(counter._eq(0),
            If(self.cntrl.vld,
               counter(ITERATIONS - 1)
            )
        ).Else(
            If(self.body.rd,
                If(self.bodyBreak,
                    counter(0)
                ).Else(
                    counter(counter - 1)
                )
            )
        )

        self.cntrl.rd(counter._eq(0))
        self.body.vld(counter != 0)
        self.index(counter[self.COUNTER_WIDTH:0])
Example #7
0
    def _impl(self):
        st_t = HEnum("state_t", ["IDLE", "LOAD_SR", "CONVERTING", "DONE"])
        st = self._reg("st", st_t, def_val=st_t.IDLE)
        sr_shift = st.next._eq(st_t.CONVERTING)

        bcd = self.din
        bin_ = self.dout
        bcd_sr = self._reg("bcd_sr", bcd.data._dtype, def_val=0)
        binary_sr = self._reg("binary_sr", bin_.data._dtype, def_val=0)
        next_bcd = rename_signal(self, bcd_sr >> 1, "next_bcd")

        MAX_COUNT = binary_sr._dtype.bit_length()
        bit_count = self._reg("bit_count", Bits(log2ceil(MAX_COUNT), signed=False), def_val=MAX_COUNT)
        If(sr_shift,
           bit_count(bit_count - 1),
        ).Else(
           bit_count(MAX_COUNT),
        )
        # dabble the digits
        digits = []
        for i in range(self.BCD_DIGITS):
            d = next_bcd[(i + 1) * 4:i * 4]._unsigned()
            d_sig = (d < 7)._ternary(d, d - 3)
            digits.append(d_sig)

        If(st.next._eq(st_t.LOAD_SR),
           bcd_sr(bcd.data),
           binary_sr(0),
        ).Elif(sr_shift,
           # shift right
           binary_sr(Concat(bcd_sr[0], binary_sr[:1])),
           bcd_sr(Concat(*reversed(digits))),
        )

        bin_.data(binary_sr)

        Switch(st)\
        .Case(st_t.IDLE,
            If(bcd.vld,
                st(st_t.LOAD_SR),  # load the shift registers
            ))\
        .Case(st_t.LOAD_SR,
            # shift right each cycle
            st(st_t.CONVERTING),
        )\
        .Case(st_t.CONVERTING,
            If(bit_count._eq(0),
                # indicate completion
                st(st_t.DONE),
            )
        )\
        .Case(st_t.DONE,
            If(bcd.vld & bin_.rd,
                st(st_t.LOAD_SR),
            ).Elif(bin_.rd,
                st(st_t.IDLE),
            )
        )
        bcd.rd(st._eq(st_t.IDLE) | (st._eq(st_t.DONE) & bin_.rd))
        bin_.vld(st._eq(st_t.DONE))
Example #8
0
    def _impl(self):
        a = self.a
        b = self.b
        out = self.dout

        st = self._reg("st", Bits(3), 1)

        If(st._eq(1),
           If(a & b,
              st(3)).Elif(b,
                          st(2))).Elif(st._eq(2),
                                       If(a & b, st(3)).Elif(a, st(1))).Elif(
                                           st._eq(3),
                                           If(a & ~b,
                                              st(1)).Elif(~a & b,
                                                          st(2))).Else(st(1))

        Switch(st)\
        .Case(1,
            out(1)
        ).Case(2,
            out(2)
        ).Case(3,
            out(3)
        ).Default(
            out(None)
        )
Example #9
0
    def _impl(self):
        output_dtype = Bits(bit_length=self.width * 2 - 1)
        output_var = self._sig(name="output_var",
                               dtype=output_dtype,
                               def_val=0)

        If(
            self.param_a[self.index],
            output_var[self.width - 1:](self.param_b[self.width - 1:]),
            If(
                self.param_b[self.width - 2],
                output_var[self.width * 2 - 1:self.width - 1](self.pow),
            ).Else(output_var[self.width * 2 - 1:self.width - 1](0)),
        ).Else(output_var(0))

        if self.index > 0:
            If(
                self.param_a[self.index],
                self.output[self.width * 2 - 1:self.index](
                    output_var[self.width * 2 - 1 - self.index:]),
                self.output[self.index:](0),
            ).Else(self.output(0))
        else:
            If(
                self.param_a[self.index],
                self.output[self.width * 2 - 1:self.index](
                    output_var[self.width * 2 - 1 - self.index:]),
            ).Else(self.output(0))
Example #10
0
    def _impl(self):
        propagateClk(self)
        PORT_CNT = self.PORT_CNT

        fa = self.firstA
        sa = self.secondA

        If(self.select_sig,
           self.ram0.port[0](fa),
           self.ram1.port[0](sa)
        ).Else(
           self.ram0.port[0](sa),
           self.ram1.port[0](fa) 
        )
        if PORT_CNT == 2:
            fb = self.firstB
            sb = self.secondB
            If(self.select_sig,
               self.ram0.port[1](fb),
               self.ram1.port[1](sb),
            ).Else(
               self.ram0.port[1](sb),
               self.ram1.port[1](fb)
            )
        elif PORT_CNT > 2:
            raise NotImplementedError()
Example #11
0
    def lookupResOfTablesDriver(self, resRead, resAck):
        tables = self.tables
        # one hot encoded index where item should be stored (where was found
        # or where is place)
        targetOH = self._reg("targetOH", Bits(self.TABLE_CNT))

        res = list(map(lambda t: t.lookupRes, tables))
        # synchronize all lookupRes from all tables
        StreamNode(masters=res).sync(resAck)

        insertFinal = self._reg("insertFinal")
        # select empty space or victim witch which current insert item
        # should be swapped with
        lookupResAck = StreamNode(masters=map(
            lambda t: t.lookupRes, tables)).ack()
        insertFoundOH = list(map(lambda t: t.lookupRes.found, tables))
        isEmptyOH = list(map(lambda t:~t.lookupRes.occupied, tables))
        _insertFinal = Or(*insertFoundOH, *isEmptyOH)

        If(resRead & lookupResAck,
            If(Or(*insertFoundOH),
                targetOH(Concat(*reversed(insertFoundOH)))
               ).Else(
                SwitchLogic([(empty, targetOH(1 << i))
                             for i, empty in enumerate(isEmptyOH)
                             ],
                            default=If(targetOH,
                                       targetOH(ror(targetOH, 1))
                                       ).Else(
                    targetOH(1 << (self.TABLE_CNT - 1))
                ))
            ),
            insertFinal(_insertFinal)
           )
        return lookupResAck, insertFinal, insertFoundOH, targetOH
Example #12
0
def AxiReaderCore():
    n = RtlNetlist()
    rSt_t = HEnum('rSt_t', ['rdIdle', 'rdData'])

    rSt = n.sig('rSt', rSt_t)
    r_idle = n.sig("r_idle")
    arRd = n.sig('arRd')
    arVld = n.sig('arVld')
    rVld = n.sig('rVld')
    rRd = n.sig('rRd')

    # ar fsm next
    If(arRd,
       # rdIdle
        If(arVld,
           rSt(rSt_t.rdData)
        ).Else(
           rSt(rSt_t.rdIdle)
        )
    ).Else(
        # rdData
        If(rRd & rVld,
           rSt(rSt_t.rdIdle)
        ).Else(
           rSt(rSt_t.rdData)
        )
    )
    r_idle(rSt._eq(rSt_t.rdIdle))
    return n, {
        r_idle: DIRECTION.OUT,
        arRd: DIRECTION.IN,
        arVld: DIRECTION.IN,
        rVld: DIRECTION.IN,
        rRd: DIRECTION.IN
    }
Example #13
0
    def _instantiateTimerTickLogic(timer: RtlSignal, period: RtlSignal,
                                   enableSig: Optional[RtlSignal],
                                   rstSig: Optional[RtlSignal]):
        """
        Instantiate incrementing timer with optional reset and enable signal

        :param timer: timer main register
        :param period: signal with actual period
        :param enableSig: optional enable signal for this timer
        :param rstSig: optional reset signal for this timer
        """

        r = timer.cntrRegister
        tick = r._eq(period - 1)
        if enableSig is None:
            if rstSig is None:
                cond = tick
            else:
                cond = rstSig | tick,

            If(cond, r(0)).Else(r(r + 0))
        else:
            if rstSig is None:
                If(enableSig, If(tick, r(0)).Else(r(r + 1)))
            else:
                If(rstSig | (enableSig & tick), r(0)).Elif(enableSig, r(r + 1))

        if enableSig is not None:
            tick = (tick & enableSig)

        if rstSig is not None:
            tick = (tick & ~rstSig)

        return tick
Example #14
0
    def __init__(self, index, name: str, parent: "OutOfOrderCummulativeOp"):
        self.index = index
        self.name = name
        r = parent._reg
        self.id = r(f"{name:s}_id", parent.m.ar.id._dtype)
        self.addr = r(f"{name:s}_addr", Bits(parent.MAIN_STATE_INDEX_WIDTH))

        if parent.TRANSACTION_STATE_T is not None:
            self.transaction_state = r(f"{name:s}_transaction_state",
                                       parent.TRANSACTION_STATE_T)
        self.data = r(f"{name:s}_data", parent.MAIN_STATE_T)

        vld = self.valid = r(f"{name:s}_valid", def_val=0)
        inVld = self.in_valid = parent._sig(f"{name:s}_in_valid")
        outRd = self.out_ready = parent._sig(f"{name:s}_out_ready")
        inRd = self.in_ready = parent._sig(f"{name:s}_in_ready")
        regs_we = self.load_en = parent._sig(f"{name:s}_load_en")

        If(self.valid, inRd(outRd), regs_we(inVld & outRd),
           If(outRd & ~inVld, vld(0))).Else(
               inRd(1),
               regs_we(inVld),
               vld(inVld),
           )

        # :note: constructed later
        self.collision_detect = None
Example #15
0
def AxiReaderCore():
    n = RtlNetlist()
    rSt_t = HEnum('rSt_t', ['rdIdle', 'rdData'])

    rSt = n.sig('rSt', rSt_t)
    arRd = n.sig('arRd')
    arVld = n.sig('arVld')
    rVld = n.sig('rVld')
    rRd = n.sig('rRd')

    # ar fsm next
    If(arRd,
       # rdIdle
        If(arVld,
           rSt(rSt_t.rdData)
        ).Else(
           rSt(rSt_t.rdIdle)
        )
    ).Else(
        # rdData
        If(rRd & rVld,
           rSt(rSt_t.rdIdle)
        ).Else(
           rSt(rSt_t.rdData)
        )
    )

    return n, [rSt, arRd, arVld, rVld, rRd]
Example #16
0
    def _impl(self):
        signal_width = Bits(bit_length=self.width, force_vector=True)
        inputs = [
            self._sig(name=f"input{i}", dtype=signal_width) for i in range(4)
        ]
        for i in range(4):
            inputs[i](self.input[(i + 1) * self.width:i * self.width])

        first_pool0 = self._sig(name="first_pool0", dtype=signal_width)
        first_pool1 = self._sig(name="first_pool1", dtype=signal_width)
        pool_result = self._sig(name="pool_result", dtype=signal_width)

        comparison = self.__bin_comparison if self.binary else self.__comparison

        comparison(inputs[0], inputs[1], first_pool0)
        comparison(inputs[2], inputs[3], first_pool1)

        If(self.rst, pool_result(0)).Else(
            If(
                self.clk._onRisingEdge(),
                If(self.en_pool,
                   comparison(first_pool0, first_pool1, pool_result)),
            ))

        self.output(pool_result)
Example #17
0
    def split_select(self, outputSelSignalOrSequence, noOfOutputs):
        """
        Create a demultiplexer with number of outputs specified by noOfOutputs

        :param noOfOutputs: number of outputs of multiplexer
        :param outputSelSignalOrSequence: handshaked interface (onehot encoded)
            to control selected output or sequence of output indexes
            which should be used (will be repeated)
        """
        if not self.master_to_slave:
            assert len(self.end) == noOfOutputs, self.end

        def setChCnt(u):
            u.OUTPUTS = noOfOutputs

        self._genericInstance(self.SplitSelectCls, 'select', setChCnt)
        if isinstance(outputSelSignalOrSequence, Handshaked):
            self.lastComp.selectOneHot(outputSelSignalOrSequence)
        else:
            seq = outputSelSignalOrSequence
            t = Bits(self.lastComp.selectOneHot.data._dtype.bit_length())
            size = len(seq)
            ohIndexes = map(lambda x: 1 << x, seq)
            indexes = self.parent._sig(self.name + "split_seq",
                                       t[size],
                                       def_val=ohIndexes)
            actual = self.parent._reg(self.name + "split_seq_index",
                                      Bits(size.bit_length()), 0)
            iin = self.lastComp.selectOneHot
            iin.data(indexes[actual])
            iin.vld(1)
            If(iin.rd,
               If(actual._eq(size - 1), actual(0)).Else(actual(actual + 1)))

        return self
Example #18
0
    def _impl(self):
        r = self.r
        w = self.w
        ram = self.ram

        readRegEmpty = self._reg("readRegEmpty", defVal=1)
        readDataPending = self._reg("readDataPending", defVal=0)
        readData = self._reg("readData", r.data.data._dtype)

        rEn = readRegEmpty | r.data.rd
        readDataPending(r.addr.vld & rEn)
        If(readDataPending, readData(ram.dout))

        If(r.data.rd, readRegEmpty(~readDataPending)).Else(
            readRegEmpty(~(readDataPending | ~readRegEmpty)))

        r.addr.rd(rEn)

        If(rEn & r.addr.vld, ram.we(0),
           ram.addr(r.addr.data)).Else(ram.we(1), ram.addr(w.addr))
        wEn = ~rEn | ~r.addr.vld
        w.rd(wEn)

        ram.din(w.data)
        ram.en((rEn & r.addr.vld) | w.vld)
        r.data.data(readData)
        r.data.vld(~readRegEmpty)
Example #19
0
    def _impl(self):
        concat_type = Bits(bit_length=self.width * 2 - 1, force_vector=True)
        concat_inputs = [
            self._sig(name=f"concat_inputs_{i}", dtype=concat_type)
            for i in range(15)
        ]
        data_type = Bits(bit_length=15, force_vector=True)
        data_a = self._sig(name="data_a", dtype=data_type, def_val=0)
        data_b = self._sig(name="data_b", dtype=data_type, def_val=0)
        non_zero_a = self._sig(name="non_zero_a", dtype=Bits(1))
        non_zero_b = self._sig(name="non_zero_b", dtype=Bits(1))
        xor_signal = self._sig(name="xor_signal", dtype=Bits(1))

        data_a[self.width - 1:](self.param_a[self.width - 1:])
        data_b[self.width - 1:](self.param_b[self.width - 1:])

        for i in range(15):
            self.concat_units[i].param_a(data_a)
            self.concat_units[i].param_b(data_b)
            concat_inputs[i](self.concat_units[i].output)
        fourth_sum = self.__calc_tree_adders(concat_inputs)

        If(data_a._eq(0), non_zero_a(0)).Else(non_zero_a(1))
        If(data_b._eq(0), non_zero_b(0)).Else(non_zero_b(1))

        xor_signal(self.param_a[self.width - 1] ^ self.param_b[self.width - 1])

        self.product[self.width - 1](xor_signal & non_zero_a & non_zero_b)
        self.product[self.width - 1:](
            fourth_sum[self.lower_output_bit + self.width -
                       1:self.lower_output_bit])
Example #20
0
    def read_logic(self, r: RamHsR, ram: BramPort_withoutClk):
        readDataPending = self._reg("readDataPending", def_val=0)
        readData = self._reg("readData",
                             HStruct((r.data.data._dtype, "data"),
                                     (BIT, "vld")),
                             def_val={"vld": 0})
        readDataOverflow = self._reg("readDataOverflow",
                                     readData._dtype,
                                     def_val={"vld": 0})

        rEn = ~readDataOverflow.vld & (~readData.vld | r.data.rd)
        readDataPending(r.addr.vld & rEn)
        If(
            readDataPending,
            If(
                ~readData.vld | r.data.rd,
                # can store directly to readData register
                readData.data(ram.dout),
                readData.vld(1),
                readDataOverflow.vld(0),
            ).Else(
                # need to store to overflow register
                readDataOverflow.data(ram.dout),
                readDataOverflow.vld(1),
            ),
        ).Else(
            If(r.data.rd, readData.data(readDataOverflow.data),
               readData.vld(readDataOverflow.vld), readDataOverflow.vld(0)))

        r.addr.rd(rEn)

        return rEn, readData
Example #21
0
    def filter(self, name, sig):
        """attempt to remove glitches"""
        filter0 = self._reg(name + "_filter0", dtype=Bits(2), defVal=0)
        filter0(filter0[0]._concat(sig))

        # let filter_cnt to be shared between filters
        try:
            filter_clk_cntr = self.filter_clk_cntr
        except AttributeError:
            filter_clk_cntr = self.filter_clk_cntr = self._reg("filter_clk_cntr",
                                                               Bits(self.CLK_CNTR_WIDTH),
                                                               defVal=self.clk_cnt_initVal)
            If(filter_clk_cntr._eq(0),
               filter_clk_cntr(self.clk_cnt_initVal)
            ).Else(
               filter_clk_cntr(filter_clk_cntr - 1)
            )

        filter1 = self._reg(name + "_filter1", dtype=Bits(3), defVal=0b111)
        If(filter_clk_cntr._eq(0),
           filter1(Concat(filter1[2:], filter0[1]))
        )

        filtered = ((filter1[2] & filter1[1]) | 
                    (filter1[2] & filter1[0]) | 
                    (filter1[1] & filter1[0]))
        return filtered
Example #22
0
    def _impl(self):
        propagateClkRstn(self)
        cntr = self._reg("wordCntr", Bits(log2ceil(self.MAX_LEN)), defVal=0)
        en = self._reg("enable", defVal=0)
        _len = self._reg("wordCntr", Bits(log2ceil(self.MAX_LEN)), defVal=0)

        self.conv.bus(self.cntrl)
        cEn = self.conv.decoded.enable
        If(cEn.dout.vld, connect(cEn.dout.data, en, fit=True))
        connect(en, cEn.din, fit=True)

        cLen = self.conv.decoded.len
        If(cLen.dout.vld, connect(cLen.dout.data, _len, fit=True))
        connect(_len, cLen.din, fit=True)

        out = self.axis_out
        connect(cntr, out.data, fit=True)
        if self.USE_STRB:
            out.strb(mask(self.axis_out.strb._dtype.bit_length()))
        out.last(cntr._eq(0))
        out.valid(en)

        If(cLen.dout.vld, connect(cLen.dout.data, cntr, fit=True)).Else(
            If(out.ready & en,
               If(cntr._eq(0), cntr(_len)).Else(cntr(cntr - 1))))
Example #23
0
    def _downscale(self, factor):
        inputRegs_cntr = self._reg("inputRegs_cntr",
                                   Bits(log2ceil(factor + 1), False),
                                   def_val=0)

        # instantiate HandshakedReg, handshaked builder is not used to avoid dependencies
        inReg = HandshakedReg(self.intfCls)
        inReg._updateParamsFrom(self.dataIn)
        self.inReg = inReg
        inReg.clk(self.clk)
        inReg.rst_n(self.rst_n)
        inReg.dataIn(self.dataIn)
        dataIn = inReg.dataOut
        dataOut = self.dataOut

        # create output mux
        for din, dout in zip(self.get_data(dataIn), self.get_data(dataOut)):
            widthOfPart = din._dtype.bit_length() // factor
            inParts = iterBits(din, bitsInOne=widthOfPart)
            Switch(inputRegs_cntr).add_cases(
                [(i, dout(inPart)) for i, inPart in enumerate(inParts)]
                )
        vld = self.get_valid_signal
        rd = self.get_ready_signal
        vld(dataOut)(vld(dataIn))
        self.get_ready_signal(dataIn)(inputRegs_cntr._eq(factor - 1) & rd(dataOut))

        If(vld(dataIn) & rd(dataOut),
            If(inputRegs_cntr._eq(factor - 1),
               inputRegs_cntr(0)
            ).Else(
               inputRegs_cntr(inputRegs_cntr + 1)
            )
        )
Example #24
0
    def axiWHandler(self, wErrFlag):
        w = self.w
        wIn = self.driver.w

        wInfo = self.writeInfoFifo.dataOut
        bInfo = self.bInfoFifo.dataIn

        if hasattr(w, "id"):
            # AXI3 has, AXI4 does not
            w.id(wInfo.id)
        w.data(wIn.data)
        w.strb(wIn.strb)

        if self.useTransSplitting():
            wordCntr = self._reg("wWordCntr", self.a.len._dtype, 0)
            doSplit = wordCntr._eq(self.getAxiLenMax()) | wIn.last

            If(
                StreamNode([wInfo, wIn], [bInfo, w]).ack(),
                If(doSplit, wordCntr(0)).Else(wordCntr(wordCntr + 1)))

        else:
            doSplit = wIn.last

        extraConds = {wInfo: doSplit, bInfo: doSplit, w: ~wErrFlag}
        w.last(doSplit)

        bInfo.isLast(wIn.last)
        StreamNode(masters=[wIn, wInfo],
                   slaves=[bInfo, w],
                   extraConds=extraConds).sync()
Example #25
0
    def _impl(self):
        self._parseTemplate()
        # build read data output mux

        st_t = HEnum('st_t', ['idle', 'readDelay', 'rdData'])
        bus = self.bus
        addr = bus.address
        addrVld = bus.read | bus.write

        st = FsmBuilder(self, st_t)\
            .Trans(st_t.idle,
                (addrVld & bus.read, st_t.rdData),
                (addrVld & bus.write, st_t.idle)
            ).Trans(st_t.readDelay,
                st_t.rdData
            ).Trans(st_t.rdData,
                st_t.idle
            ).stateReg

        wAck = True
        wr = bus.write & wAck
        isInAddrRange = (self.isInMyAddrRange(bus.address))

        If(isInAddrRange,
            bus.response(RESP_OKAY)
        ).Else(
            bus.response(RESP_SLAVEERROR)
        )
        bus.waitRequest(bus.read & ~st._eq(st_t.rdData))
        bus.readDataValid(st._eq(st_t.rdData))
        bus.writeResponseValid(wr)

        ADDR_STEP = self._getAddrStep()
        dataToBus = bus.readData(None)
        for (_, _), t in reversed(self._bramPortMapped):
            # map addr for bram ports
            _addr = t.bitAddr // ADDR_STEP
            _isMyAddr = inRange(addr, _addr, t.bitAddrEnd // ADDR_STEP)
            wasMyAddr = self._reg("wasMyAddr")
            If(st._eq(st_t.idle),
                wasMyAddr(_isMyAddr)
            )
            port = self.getPort(t)

            self.propagateAddr(addr, ADDR_STEP, port.addr,
                               port.dout._dtype.bit_length(), t)

            port.en(_isMyAddr & addrVld)
            port.we(_isMyAddr & wr)

            dataToBus = If(wasMyAddr & st._eq(st_t.rdData),
                           bus.readData(port.dout)
                        ).Else(
                            dataToBus
                        )

            port.din(bus.writeData)

        self.connect_directly_mapped_write(addr, bus.writeData, wr)
        self.connect_directly_mapped_read(bus.address, bus.readData, dataToBus)
Example #26
0
    def _impl(self):
        propagateClkRstn(self)
        r = self._reg

        START_BIT = hBit(0)
        STOP_BIT = hBit(1)
        BITS_TO_SEND = 1 + 8 + 1
        BIT_RATE = self.FREQ // self.BAUD

        assert BIT_RATE >= 1

        din = self.dataIn

        data = r("data", Bits(BITS_TO_SEND))  # data + start bit + stop bit
        en = r("en", defVal=False)
        tick, last = ClkBuilder(self, self.clk).timers(
            [BIT_RATE, BIT_RATE * BITS_TO_SEND], en)

        If(~en & din.vld, data(Concat(STOP_BIT, din.data, START_BIT)),
           en(1)).Elif(
               tick & en,
               # srl where 1 is shifted from left
               data(hBit(1)._concat(data[:1])),
               If(
                   last,
                   en(0),
               ))
        din.rd(~en)

        txd = r("reg_txd", defVal=1)
        If(tick & en, txd(data[0]))
        self.txd(txd)
Example #27
0
    def _impl(self) -> None:
        start = self._sig("start")
        part_res_t = Bits(self.DATA_WIDTH)
        # High-order n bits of product
        a = self._reg("a", part_res_t)
        # multiplicand
        m = self._reg("m", part_res_t)
        # Initially holds multiplier, ultimately holds low-order n bits of product
        q = self._reg("q", part_res_t)
        # previous bit 0 of q
        q_1 = self._reg("q_1")

        din = self.dataIn
        dout = self.dataOut

        counter = self._reg(
            "counter",
            Bits(log2ceil(self.DATA_WIDTH + 1), signed=False),
            def_val=0)
        done = counter._eq(0)
        waitinOnConsumer = self._reg("waitinOnConsumer", def_val=0)

        add = rename_signal(self, (a + m)._signed(), "add")
        sub = rename_signal(self, (a - m)._signed(), "sub")

        If(start,
            a(0),
            m(din.a),
            q(din.b),
            q_1(0),
            counter(self.DATA_WIDTH),
        ).Elif(~done,
            Switch(Concat(q[0], q_1))
            .Case(0b01,
                # add multiplicand to left half of product
                a(add >> 1),
                q(Concat(add[0], q[:1])),
            ).Case(0b10,
                # substract multiplicand from left half of product
                a(sub >> 1),
                q(Concat(sub[0], q[:1])),
            ).Default(
                a(a._signed() >> 1),
                q(Concat(a[0], q[:1])),
            ),
            q_1(q[0]),
            counter(counter - 1)
        )

        If(start,
            waitinOnConsumer(1)
        ).Elif(done & dout.rd,
            waitinOnConsumer(0),
        )

        dout.data(Concat(a, q)._vec())
        dout.vld(done & waitinOnConsumer)
        start(din.vld & done & ~waitinOnConsumer)
        din.rd(done & ~waitinOnConsumer)
Example #28
0
    def fifo_pointers(self, DEPTH: int,
                      write_en_wait: Tuple[RtlSignal, RtlSignal],
                      read_en_wait_list: List[Tuple[RtlSignal, RtlSignal]])\
                      -> List[Tuple[RtlSignal, RtlSignal]]:
        """
        Create fifo writer and reader pointers and enable/wait logic
        This functions supports multiple reader pointers

        :attention: writer pointer next logic check only last reader pointer
        :return: list, tule(en, ptr) for writer and each reader
        """
        index_t = Bits(log2ceil(DEPTH), signed=False)
        # assert isPow2(DEPTH), DEPTH
        MAX_DEPTH = DEPTH - 1
        s = self._sig
        r = self._reg
        fifo_write = s("fifo_write")
        write_ptr = _write_ptr = r("write_ptr", index_t, 0)
        ack_ptr_list = [
            (fifo_write, write_ptr),
        ]
        # update writer (head) pointer as needed
        If(
            fifo_write,
            If(write_ptr._eq(MAX_DEPTH),
               write_ptr(0)).Else(write_ptr(write_ptr + 1)))

        write_en, _ = write_en_wait
        # instantiate all read pointers
        for i, (read_en, read_wait) in enumerate(read_en_wait_list):
            read_ptr = r(f"read_ptr{i:d}", index_t, 0)
            fifo_read = s(f"fifo_read{i:d}")
            ack_ptr_list.append((fifo_read, read_ptr))
            # update reader (tail) pointer as needed
            If(
                fifo_read,
                If(read_ptr._eq(MAX_DEPTH),
                   read_ptr(0)).Else(read_ptr(read_ptr + 1)))

            looped = r(f"looped{i:d}", def_val=False)
            # looped logic
            If(write_en & write_ptr._eq(MAX_DEPTH),
               looped(True)).Elif(read_en & read_ptr._eq(MAX_DEPTH),
                                  looped(False))

            # Update Empty and Full flags
            read_wait(write_ptr._eq(read_ptr) & ~looped)
            fifo_read(read_en & (looped | (write_ptr != read_ptr)))
            # previous reader is next port writer (producer) as it next reader can continue only if previous reader did consume the item
            write_en, _ = read_en, read_wait
            write_ptr = read_ptr

        write_en, write_wait = write_en_wait
        write_ptr = _write_ptr
        # Update Empty and Full flags
        write_wait(write_ptr._eq(read_ptr) & looped)
        fifo_write(write_en & (~looped | (write_ptr != read_ptr)))

        return ack_ptr_list
Example #29
0
    def _impl(self):
        START_BIT = 0
        STOP_BIT = 1

        os = int(self.OVERSAMPLING)
        baud = int(self.BAUD)
        freq = int(self.FREQ)
        assert freq >= baud * os, "Frequency too low for current Baud rate and oversampling"
        assert os >= 8 and (os & (os - 1)) == 0, "Invalid oversampling value"

        propagateClkRstn(self)

        clkBuilder = ClkBuilder(self, self.clk)

        en = self._reg("en", defVal=0)
        first = self._reg("first", defVal=1)
        RxD_data = self._reg("RxD_data", Bits(1 + 8))
        startBitWasNotStartbit = self._sig("startBitWasNotStartbit")
        # it can happen that there is just glitch on wire and bit was not startbit only begin was resolved wrong
        # eval because otherwise vhdl int overflows
        sampleTick = clkBuilder.timer(
            ("sampleTick", self.FREQ // self.BAUD // self.OVERSAMPLING),
            enableSig=en,
            rstSig=~en)

        # synchronize RxD to our clk domain
        RxD_sync = self._reg("RxD_sync", defVal=1)
        RxD_sync(self.rxd)

        rxd, rxd_vld = clkBuilder.oversample(RxD_sync,
                                             self.OVERSAMPLING,
                                             sampleTick,
                                             rstSig=~en)

        isLastBit = clkBuilder.timer(("isLastBitTick", 10),
                                     enableSig=rxd_vld,
                                     rstSig=~en)
        If(
            en,
            If(
                rxd_vld,
                RxD_data(Concat(rxd, RxD_data[9:1])),  # shift data from left
                If(
                    startBitWasNotStartbit,
                    en(0),
                    first(1),
                ).Else(
                    en(~isLastBit),
                    first(isLastBit),
                ))).Elif(
                    RxD_sync._eq(START_BIT),
                    # potential start bit detected, begin scanning sequence
                    en(1),
                )
        startBitWasNotStartbit(first & rxd_vld & (rxd != START_BIT))
        self.dataOut.vld(isLastBit & RxD_data[0]._eq(START_BIT)
                         & rxd._eq(STOP_BIT))

        self.dataOut.data(RxD_data[9:1])
Example #30
0
    def _impl(self):
        r = self._reg("reg_d", Bits(2), def_val=0)

        If(self.a & self.b, If(
            self.c,
            r(0),
        )).Elif(self.c, r(1)).Else(r(2))
        self.d(r)
Example #31
0
    def test_baicIf(self):
        a = self.n.sig('a')
        b = self.n.sig('b')

        obj = If(a,
                 b(1)
                 ).Else(
            b(0)
        )

        container, io_change = obj._try_reduce()
        self.assertFalse(io_change)
        self.assertEqual(len(container), 1)
        container = container[0]
        tmpl = IfContainer(a,
                           ifTrue=[b(1)],
                           ifFalse=[b(0)])
        self.compareStructure(tmpl, container)