Пример #1
0
    def select_data_word_from_ouput_word(self, m, s):
        w_align_fifo = self.propagate_addr(m.aw, s.aw)
        r_align_fifo = self.propagate_addr(m.ar, s.ar)
        AL_IN_W = self.ALIGN_BITS_IN
        AL_OUT_W = self.ALIGN_BITS_OUT
        ALIG_W = AL_OUT_W - AL_IN_W
        assert ALIG_W > 0, ALIG_W
        r_align_cases = []
        w_align_cases = []
        for i in range(2**ALIG_W):
            r_align_cases.append((i, self.connect_shifted(s.r, m.r, i)))
            w_align_cases.append((i, self.connect_shifted(m.w, s.w, i)))

        s.w(m.w, exclude={m.w.data, m.w.strb, m.w.ready, m.w.valid})
        StreamNode(masters=[m.w, w_align_fifo.dataOut], slaves=[s.w]).sync()
        Switch(w_align_fifo.dataOut.data).add_cases(w_align_cases)\
            .Default(
                # case which was unexpected or was filtered out by IN_ADDR_GRANULARITY
                s.w.data(None),
                s.w.strb(None),
            )

        m.r(s.r, exclude={s.r.data, s.r.ready, s.r.valid})
        StreamNode(masters=[s.r, r_align_fifo.dataOut], slaves=[m.r]).sync()
        Switch(r_align_fifo.dataOut.data).add_cases(r_align_cases)\
            .Default(
                # case which was unexpected or was filtered out by IN_ADDR_GRANULARITY
                m.r.data(None),
            )

        m.b(s.b)
Пример #2
0
 def test_SwitchContainer_try_reduce__empty(self):
     nl = RtlNetlist()
     a = nl.sig("a", BIT)
     s0 = Switch(a).add_cases([(hBit(0), []), (hBit(1), [])])
     s0_red, io_change = s0._try_reduce()
     self.assertFalse(io_change)
     self.assertEqual(s0_red, [])
Пример #3
0
    def _impl(self):
        self._parseTemplate()
        bus = self.bus

        def connectRegIntfAlways(regIntf, _addr):
            return (
                c(bus.din, regIntf.dout.data) +
                c(bus.we & bus.en & bus.addr._eq(_addr), regIntf.dout.vld)
            )

        ADDR_STEP = self._getAddrStep()
        if self._directlyMapped:
            readReg = self._reg("readReg", dtype=bus.dout._dtype)
            # tuples (condition, assign statements)
            readRegInputs = []
            for t in self._directlyMapped:
                port = self.getPort(t)
                _addr = t.bitAddr // ADDR_STEP
                connectRegIntfAlways(port, _addr)
                readRegInputs.append((bus.addr._eq(_addr),
                                      readReg(port.din)
                                      ))
            SwitchLogic(readRegInputs)
        else:
            readReg = None

        if self._bramPortMapped:
            BRAMS_CNT = len(self._bramPortMapped)
            bramIndxCases = []
            readBramIndx = self._reg("readBramIndx", Bits(
                log2ceil(BRAMS_CNT + 1), False))
            outputSwitch = Switch(readBramIndx)

            for i, t in enumerate(self._bramPortMapped):
                # if we can use prefix instead of addr comparing do it
                _addr = t.bitAddr // ADDR_STEP
                _addrEnd = t.bitAddrEnd // ADDR_STEP
                port = self.getPort(t)

                _addrVld, _ = self.propagateAddr(bus.addr,
                                                 ADDR_STEP,
                                                 port.addr,
                                                 port.dout._dtype.bit_length(),
                                                 t)

                port.we(bus.we & _addrVld & bus.en)
                port.en(bus.en & _addrVld & bus.en)
                port.din(bus.din)

                bramIndxCases.append((_addrVld, readBramIndx(i)))
                outputSwitch.Case(i, bus.dout(port.dout))

            outputSwitch.Default(bus.dout(readReg))
            SwitchLogic(bramIndxCases,
                        default=readBramIndx(BRAMS_CNT))
        else:
            bus.dout(readReg)
Пример #4
0
    def generate_output_byte_mux(self, regs):
        out_mux_values = [set() for _ in range(self.word_bytes)]
        for st in self.state_trans_table.state_trans:
            for stt in st:
                for o_mux_val, out_mux_val_set in zip(stt.out_byte_mux_sel,
                                                      out_mux_values):
                    if o_mux_val is not None:
                        out_mux_val_set.add(o_mux_val)
        out_mux_values = [sorted(x) for x in out_mux_values]

        def index_byte(sig, byte_i):
            return sig[(byte_i+1)*8:byte_i*8]

        def get_in_byte(input_i, time_offset, byte_i):
            return index_byte(regs[input_i][time_offset].data, byte_i)

        def data_drive(out_B, out_strb_b, input_i, time_offset, byte_i):
            res = [
                out_B(get_in_byte(input_i, time_offset, byte_i))
            ]
            if self.USE_STRB:
                res.append(
                   out_strb_b(regs[input_i][time_offset].strb[byte_i])
                )
            return res

        out_byte_sel = []
        for out_B_i, out_byte_mux_vals in enumerate(out_mux_values):
            # +1 because last value is used to invalidate data
            sel_w = log2ceil(len(out_byte_mux_vals) + 1)
            sel = self._sig(f"out_byte{out_B_i:d}_sel", Bits(sel_w))
            out_byte_sel.append(sel)

            out_B = self._sig(f"out_byte{out_B_i:d}", Bits(8))
            index_byte(self.dataOut.data, out_B_i)(out_B)

            if self.USE_STRB:
                out_strb_b = self._sig(f"out_strb{out_B_i:d}")
                self.dataOut.strb[out_B_i](out_strb_b)
            else:
                out_strb_b = None

            sw = Switch(sel).add_cases(
                (i, data_drive(out_B, out_strb_b, *val))
                for i, val in enumerate(out_byte_mux_vals))
            # :note: default case is threre for the case of faulire where
            #     sel has non predicted value
            default_case = [out_B(None)]
            if self.USE_STRB:
                default_case.append(out_strb_b(0))
            sw.Default(*default_case)
        return out_byte_sel, out_mux_values
Пример #5
0
    def test_basicSwitch(self):
        a = self.n.sig('a', dtype=INT)
        b = self.n.sig('b', dtype=INT)

        obj = Switch(a).addCases([(i, c(i, b)) for i in range(4)])
        cont, io_change = obj._try_reduce()
        self.assertFalse(io_change)
        self.assertEqual(len(cont), 1)
        cont = cont[0]

        tmpl = SwitchContainer(a, [(i, c(i, b))
                                   for i in range(3)] + [(None, c(3, b))])
        self.compareStructure(tmpl, cont)
Пример #6
0
 def test_SwitchContainer_try_reduce__all(self):
     nl = RtlNetlist()
     a = nl.sig("a", BIT)
     b = nl.sig("b", BIT)
     s0 = Switch(a).add_cases([(hBit(0), [
         b(0),
     ]), (hBit(1), [
         b(0),
     ])])
     s0_red, io_change = s0._try_reduce()
     self.assertFalse(io_change)
     self.assertEqual(len(s0_red), 1)
     self.assertTrue(s0_red[0].isSame(b(0)))
Пример #7
0
    def test_basicSwitch(self):
        a = self.n.sig('a', dtype=INT)
        b = self.n.sig('b', dtype=INT)

        obj = Switch(a).addCases([(i, c(i, b)) for i in range(4)])
        cont, io_change = obj._try_reduce()
        self.assertFalse(io_change)
        self.assertEqual(len(cont), 1)
        cont = cont[0]

        tmpl = SwitchContainer(a, [(i, c(i, b)) for i in range(3)]
                               + [(None, c(3, b))])
        self.compareStructure(tmpl, cont)
Пример #8
0
    def _impl(self):
        # :note: stT member names are colliding with port names and thus
        #     they will be renamed in HDL
        stT = HEnum("st_t", ["a", "b", "aAndB"])

        a = self.a
        b = self.b
        out = self.dout

        st = FsmBuilder(self, stT)\
        .Trans(stT.a,
            (a & b, stT.aAndB),
            (b, stT.b)
        ).Trans(stT.b,
            (a & b, stT.aAndB),
            (a, stT.a)
        ).Trans(stT.aAndB,
            (a & ~b, stT.a),
            (~a & b, stT.b),
        ).stateReg

        Switch(st)\
        .Case(stT.a,
              out(1)
        ).Case(stT.b,
              out(2)
        ).Case(stT.aAndB,
              out(3)
        )
Пример #9
0
    def mainFsm(self, st, onoff, lenRem, actualLenRem):
        axi = self.axi
        st_t = st._dtype

        w_ackAll = self.w_allAck(st)

        Switch(st)\
        .Case(st_t.fullIdle,
            If(onoff,
                st(st_t.writeAddr)
            )
        ).Case(st_t.writeAddr,
            If(axi.aw.ready,
                If(lenRem._eq(1),
                   st(st_t.writeDataLast)
                ).Else(
                   st(st_t.writeData)
                )
            )
        ).Case(st_t.writeData,
            If(w_ackAll & (actualLenRem._eq(2)),
               st(st_t.writeDataLast)
            )
        ).Case(st_t.writeDataLast,
            If(w_ackAll,
                If(lenRem != 0,
                   st(st_t.writeAddr)
                ).Else(
                   st(st_t.fullIdle)
                )
            )
        )
Пример #10
0
    def wHandler(self):
        w = self.wDatapump.w
        fWOut = self.orderInfoFifoW.dataOut
        fAckIn = self.orderInfoFifoAck.dataIn

        driversW = list(map(lambda d: d.w,
                            self.drivers))

        selectedDriverVld = self._sig("selectedDriverWVld")
        selectedDriverVld(Or(*map(lambda d: fWOut.data._eq(d[0]) & d[1].valid,
                                  enumerate(driversW))
                            ))
        selectedDriverLast = self._sig("selectedDriverLast")
        selectedDriverLast(Or(*map(lambda d: fWOut.data._eq(d[0]) & d[1].last,
                                   enumerate(driversW))
                             ))

        Switch(fWOut.data).addCases(
            [(i, connect(d, w, exclude=[d.valid, d.ready]))
               for i, d in enumerate(driversW)]

        ).Default(
            w.data(None),
            w.strb(None),
            w.last(None)
        )

        fAckIn.data(fWOut.data)

        # handshake logic
        fWOut.rd(selectedDriverVld & selectedDriverLast & w.ready & fAckIn.rd)
        for i, d in enumerate(driversW):
            d.ready(fWOut.data._eq(i) & w.ready & fWOut.vld & fAckIn.rd)
        w.valid(selectedDriverVld & fWOut.vld & fAckIn.rd)
        fAckIn.vld(selectedDriverVld & selectedDriverLast & w.ready & fWOut.vld)
Пример #11
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)
            )
        )
Пример #12
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)
        )
Пример #13
0
    def _impl(self):
        stT = HEnum("st_t", ["a", "b", "aAndB"])

        a = self.a
        b = self.b
        out = self.dout

        st = FsmBuilder(self, stT)\
        .Trans(stT.a,
            (a & b, stT.aAndB),
            (b, stT.b)
        ).Trans(stT.b,
            (a & b, stT.aAndB),
            (a, stT.a)
        ).Trans(stT.aAndB,
            (a & ~b, stT.a),
            (~a & b, stT.b),
        ).stateReg

        Switch(st)\
        .Case(stT.a,
              out(1)
        ).Case(stT.b,
              out(2)
        ).Case(stT.aAndB,
              out(3)
        )
Пример #14
0
 def _impl(self):
     dec = [
         # 0
         0b0000001,
         # 1
         0b1001111,
         # 2
         0b0010010,
         # 3
         0b0000110,
         # 4
         0b1001100,
         # 5
         0b0100100,
         # 6
         0b0100000,
         # 7
         0b0001111,
         # 8
         0b0000000,
         # 9
         0b0000100,
     ]
     Switch(self.dataIn) \
     .addCases(enumerate([self.dataOut(v) for v in dec])) \
     .Default(
        # display off when value is out of range
        self.dataOut(0b1111111)
     )
Пример #15
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))
Пример #16
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)
Пример #17
0
    def _impl(self):
        self._parseTemplate()
        bus = self.bus

        ADDR_STEP = self._getAddrStep()
        if self._directly_mapped_words:
            readReg = self._reg("readReg", dtype=bus.dout._dtype)
            # tuples (condition, assign statements)
            If(bus.en,
               self.connect_directly_mapped_read(bus.addr, readReg, [])
            )
            self.connect_directly_mapped_write(bus.addr, bus.din, bus.en & bus.we)
        else:
            readReg = None

        if self._bramPortMapped:
            BRAMS_CNT = len(self._bramPortMapped)
            bramIndxCases = []
            readBramIndx = self._reg("readBramIndx", Bits(
                log2ceil(BRAMS_CNT + 1), False))
            outputSwitch = Switch(readBramIndx)

            for i, ((_, _), t) in enumerate(self._bramPortMapped):
                # if we can use prefix instead of addr comparing do it
                _addr = t.bitAddr // ADDR_STEP
                _addrEnd = t.bitAddrEnd // ADDR_STEP
                port = self.getPort(t)

                _addrVld, _ = self.propagateAddr(bus.addr,
                                                 ADDR_STEP,
                                                 port.addr,
                                                 port.dout._dtype.bit_length(),
                                                 t)

                port.we(bus.en & bus.we & _addrVld)
                port.en(bus.en & _addrVld)
                port.din(bus.din)

                bramIndxCases.append((_addrVld, readBramIndx(i)))
                outputSwitch.Case(i, bus.dout(port.dout))

            outputSwitch.Default(bus.dout(readReg))
            SwitchLogic(bramIndxCases,
                        default=readBramIndx(BRAMS_CNT))
        else:
            bus.dout(readReg)
Пример #18
0
    def test_Switch(self):
        ctx = RtlNetlist()
        a = ctx.sig("a", uint8_t)
        b = ctx.sig("b", uint8_t)
        stm = Switch(a)\
            .Case(0, b(0))\
            .Case(1, b(1))\
            .Case(2, b(2))\
            .Default(b(3))
        self.ae(stm, """\
Switch(a)\\
    .Case(0,
        b(0))\\
    .Case(1,
        b(1))\\
    .Case(2,
        b(2))\\
    .Default(
        b(3))""")
Пример #19
0
    def remSizeToStrb(self, remSize, strb):
        strbBytes = 2**self.getSizeAlignBits()

        return Switch(remSize)\
            .Case(0,
                  strb(mask(strbBytes))
                  ).addCases(
            [(i + 1, strb(mask(i + 1)))
             for i in range(strbBytes - 1)]
        )
Пример #20
0
 def _impl(self):
     Switch(self.sel)\
     .Case(0,
         self.out(self.a)
     ).Case(1,
         self.out(self.b)
     ).Case(2,
         self.out(self.c)
     ).Default(
         self.out(0)
     )
Пример #21
0
def SwitchStatement():
    t = Bits(8)
    n = RtlNetlist()

    In = n.sig("input", t, defVal=8)
    Out = n.sig("output", t)

    Switch(In).addCases([(i, Out(i + 1)) for i in range(8)])

    interf = [In, Out]
    return n, interf
Пример #22
0
def SwitchStatement():
    t = Bits(8)
    n = RtlNetlist()

    In = n.sig("input", t, def_val=8)
    Out = n.sig("output", t)

    Switch(In).add_cases([(i, Out(i + 1)) for i in range(8)])

    interf = {In: DIRECTION.IN, Out: DIRECTION.OUT}
    return n, interf
Пример #23
0
    def connect_directly_mapped_read(self, ar_addr: RtlSignal,
                                     r_data: RtlSignal, default_r_data_drive):
        """
        Connect the RegCntrl.din interfaces to a bus
        """
        DW = int(self.DATA_WIDTH)
        ADDR_STEP = self._getAddrStep()
        directlyMappedWords = []
        for (w_i, items) in self._directly_mapped_words:
            w_data = []
            last_end = w_i * DW
            for tpart in items:
                assert last_end == tpart.startOfPart, (last_end,
                                                       tpart.startOfPart)
                if tpart.tmpl is None:
                    # padding
                    din = Bits(tpart.bit_length()).from_py(None)
                else:
                    din = self.getPort(tpart.tmpl)
                    if isinstance(din, RegCntrl):
                        din = din.din
                if din._dtype.bit_length() > 1:
                    fr = tpart.getFieldBitRange()
                    din = din[fr[0]:fr[1]]
                w_data.append(din)
                last_end = tpart.endOfPart

            end_of_word = (w_i + 1) * DW
            assert last_end == end_of_word, (last_end, end_of_word)
            word_val = Concat(*reversed(w_data))
            assert word_val._dtype.bit_length() == DW, (items, word_val)
            directlyMappedWords.append((w_i * (DW // ADDR_STEP), word_val))

        mux = Switch(ar_addr).add_cases([
            (word_i, r_data(val)) for (word_i, val) in directlyMappedWords
        ])
        if default_r_data_drive:
            mux.Default(default_r_data_drive)
        return mux
Пример #24
0
    def _impl(self):
        V = self.VAL
        VAL_W = self.VAL._dtype.bit_length()
        D_W = self.DATA_WIDTH
        if not V._is_full_valid():
            raise NotImplementedError()
        din = self.dataIn
        dout = self.dataOut
        if VAL_W <= D_W:
            # do comparison in single word
            dout.data(din.data[VAL_W:]._eq(V))
            StreamNode([din], [dout]).sync()
        else:
            # build fsm for comparing
            word_cnt = ceil(VAL_W / D_W)
            word_index = self._reg("word_index",
                                   Bits(log2ceil(word_cnt - 1)),
                                   def_val=0)
            # true if all previous words were matching
            state = self._reg("state", def_val=1)
            offset = 0
            word_cases = []
            for is_last_word, i in iter_with_last(range(word_cnt)):
                val_low = offset
                val_high = min(offset + D_W, VAL_W)
                in_high = val_high - val_low
                state_update = din.data[in_high:]._eq(V[val_high:val_low])
                if is_last_word:
                    dout.data(state & state_update)
                else:
                    word_cases.append((i, state(state & state_update)))

            If(StreamNode([din], [dout]).ack(),
                If(din.last,
                   word_index(0),
                   state(1),
                ).Else(
                   word_index(word_index + 1),
                   Switch(word_index)\
                   .add_cases(word_cases)
                )
            )

            StreamNode([din], [dout],
                       extraConds={
                           dout: din.valid & din.last
                       },
                       skipWhen={
                           dout: ~(din.valid & din.last)
                       }).sync()
Пример #25
0
    def downscale(self, IN_DW, OUT_DW):
        if IN_DW % OUT_DW != 0:
            raise NotImplementedError()
        dOut = self.getDataWidthDependent(self.dataOut)

        # instantiate AxiSReg, AxiSBuilder is not used to avoid dependencies
        inReg = AxiSReg(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

        dIn = self.getDataWidthDependent(dataIn)

        ITEMS = IN_DW // OUT_DW
        itemCntr = self._reg("itemCntr", Bits(log2ceil(ITEMS + 1)), def_val=0)

        hs = StreamNode([dataIn], [self.dataOut]).ack()
        isLastItem = itemCntr._eq(ITEMS - 1)
        strbLastOverride = self.nextAreNotValidLogic(dataIn.strb, itemCntr,
                                                     ITEMS, OUT_DW)
        if strbLastOverride is not True:
            isLastItem = isLastItem | strbLastOverride

        # connected item selected by itemCntr to output
        for inp, outp in zip(dIn, dOut):
            w = outp._dtype.bit_length()
            Switch(itemCntr)\
            .add_cases([
                    (wordIndx, outp(inp[((wordIndx + 1) * w):(w * wordIndx)]))
                    for wordIndx in range(ITEMS)
            ])\
            .Default(
                outp(None)
            )

        # connect others signals directly
        for inp, outp in zip(self.get_data(dataIn),
                             self.get_data(self.dataOut)):
            if inp not in dIn and inp is not dataIn.last:
                outp(inp)

        self.dataOut.last(dataIn.last & isLastItem)
        self.get_ready_signal(dataIn)(self.get_ready_signal(self.dataOut)
                                      & isLastItem & dataIn.valid)
        self.get_valid_signal(self.dataOut)(self.get_valid_signal(dataIn))

        If(hs, If(isLastItem, itemCntr(0)).Else(itemCntr(itemCntr + 1)))
Пример #26
0
def ComplexConditions():
    n = RtlNetlist()
    stT = HEnum('t_state', ["idle", "tsWait", "ts0Wait", "ts1Wait", "lenExtr"])
    clk = n.sig('clk')
    rst = n.sig("rst")

    st = n.sig('st', stT, clk=clk, syncRst=rst, def_val=stT.idle)
    s_idle = n.sig('s_idle')
    sd0 = n.sig('sd0')
    sd1 = n.sig('sd1')
    cntrlFifoVld = n.sig('ctrlFifoVld')
    cntrlFifoLast = n.sig('ctrlFifoLast')

    def tsWaitLogic(ifNoTsRd):
        return If(sd0 & sd1, st(stT.lenExtr)).Elif(sd0, st(stT.ts1Wait)).Elif(
            sd1, st(stT.ts0Wait)).Else(ifNoTsRd)
    Switch(st)\
    .Case(stT.idle,
        tsWaitLogic(
            If(cntrlFifoVld,
               st(stT.tsWait)
            )
        )
    ).Case(stT.tsWait,
        tsWaitLogic(st(st))
    ).Case(stT.ts0Wait,
        If(sd0,
           st(stT.lenExtr)
        )
    ).Case(stT.ts1Wait,
        If(sd1,
           st(stT.lenExtr)
        )
    ).Case(stT.lenExtr,
        If(cntrlFifoVld & cntrlFifoLast,
           st(stT.idle)
        )
    )
    s_idle(st._eq(stT.idle))

    return n, {
        rst: DIRECTION.IN,
        clk: DIRECTION.IN,
        sd0: DIRECTION.IN,
        sd1: DIRECTION.IN,
        cntrlFifoVld: DIRECTION.IN,
        cntrlFifoLast: DIRECTION.IN,
        s_idle: DIRECTION.OUT
    }
Пример #27
0
    def _impl(self):
        assert (int(self.USER_WIDTH) == 2)  # this is how is protocol specified
        In = self.dataIn
        Out = self.dataOut

        propagateClkRstn(self)
        lastSeenLast = self._reg("lastSeenLast", defVal=1)
        sof = lastSeenLast

        Out.data(In.data)
        Out.src_rdy_n(~In.valid)

        outRd = ~Out.dst_rdy_n
        If(In.valid & outRd, lastSeenLast(In.last))
        In.ready(outRd)

        Out.eof_n(~In.last)

        # AXI_USER(0) -> FL_SOP_N
        # Always set FL_SOP_N when FL_SOF_N - added for compatibility with xilinx
        # axi components. Otherwise FL_SOP_N would never been set and LocalLink
        # protocol would be broken.
        sop = In.user[0]
        If(sof, Out.sop_n(0)).Else(Out.sop_n(~sop))

        # AXI_USER(1) -> FL_EOP_N
        # Always set FL_EOP_N when FL_EOF_N - added for compatibility with xilinx
        # axi components. Otherwise FL_EOP_N would never been set and LocalLink
        # protocol would be broken.
        eop = In.user[1]
        If(In.last, Out.eop_n(0)).Else(Out.eop_n(~eop))

        remMap = []
        remBits = Out.rem._dtype.bit_length()
        strbBits = In.strb._dtype.bit_length()

        for strb, rem in strbToRem(strbBits, remBits):
            remMap.append((strb, Out.rem(rem)))

        end_of_part_or_transaction = In.last | eop

        If(end_of_part_or_transaction,
            Switch(In.strb)\
            .addCases(remMap)
        ).Else(
            Out.rem(mask(remBits))
        )

        Out.sof_n(~sof)
Пример #28
0
    def _impl(self):
        self.DATA_WIDTH = int(self.DATA_WIDTH)
        vldAll = mask(self.DATA_WIDTH // 8)
        dout = self.dataOut
        DATA_LEN = len(self.DATA)

        wordIndex_w = int(math.log2(DATA_LEN) + 1)
        wordIndex = self._reg("wordIndex", Bits(wordIndex_w), def_val=0)

        Switch(wordIndex)\
            .add_cases([(i, dout.data(d))
                       for i, d in enumerate(self.DATA)])\
            .Default(dout.data(None))

        dout.last(wordIndex._eq(DATA_LEN - 1))
        If(wordIndex < DATA_LEN, dout.strb(vldAll),
           dout.valid(1)).Else(dout.strb(None), dout.valid(0))

        If(self.dataRd(), self.nextWordIndexLogic(wordIndex))
Пример #29
0
    def _impl(self):
        self.DATA_WIDTH = int(self.DATA_WIDTH)
        dout = self.dataOut
        DATA_LEN = len(self.DATA)

        wordIndex_w = int(math.log2(DATA_LEN) + 1)
        wordIndex = self._reg("wordIndex", Bits(wordIndex_w), def_val=0)

        def set_data(d):
            return self.set_data(dout, d)

        Switch(wordIndex)\
            .add_cases([(i, set_data(d))
                       for i, d in enumerate(self.DATA)])\
            .Default(*set_data(None))

        If(wordIndex < DATA_LEN, dout.vld(1)).Else(dout.vld(0))

        If(self.dataRd(), self.nextWordIndexLogic(wordIndex))
Пример #30
0
    def _impl(self):
        propagateClkRstn(self)
        ITEM_WIDTH = int(self.ITEM_WIDTH)
        DATA_WIDTH = int(self.DATA_WIDTH)
        ITEMS_IN_DATA_WORD = self.ITEMS_IN_DATA_WORD
        ITEM_SIZE_IN_WORDS = 1

        if ITEM_WIDTH % 8 != 0 or ITEM_SIZE_IN_WORDS * DATA_WIDTH != ITEMS_IN_DATA_WORD * ITEM_WIDTH:
            raise NotImplementedError(ITEM_WIDTH)

        req = self.rDatapump.req
        req.id(self.ID)
        req.len(ITEM_SIZE_IN_WORDS - 1)
        req.rem(0)

        if ITEMS_IN_DATA_WORD == 1:
            addr = Concat(self.index.data, vec(0, log2ceil(ITEM_WIDTH // 8)))
            req.addr(self.base + fitTo(addr, req.addr))
            StreamNode(masters=[self.index], slaves=[req]).sync()

            self.item.data(self.rDatapump.r.data)
            StreamNode(masters=[self.rDatapump.r], slaves=[self.item]).sync()

        else:
            r = self.rDatapump.r.data
            f = self.itemSubIndexFifo
            subIndexBits = f.dataIn.data._dtype.bit_length()
            itemAlignBits = log2ceil(ITEM_WIDTH // 8)
            addr = Concat(self.index.data[:subIndexBits],
                          vec(0, itemAlignBits + subIndexBits))

            req.addr(self.base + fitTo(addr, req.addr))
            f.dataIn.data(self.index.data[subIndexBits:])
            StreamNode(masters=[self.index], slaves=[req, f.dataIn]).sync()

            Switch(f.dataOut.data).addCases([
                (ITEMS_IN_DATA_WORD - i - 1,
                 self.item.data(r[(ITEM_WIDTH * (i + 1)):(ITEM_WIDTH * i)]))
                for i in range(ITEMS_IN_DATA_WORD)
            ])
            StreamNode(masters=[self.rDatapump.r, f.dataOut],
                       slaves=[self.item]).sync()
Пример #31
0
    def handler_data_mux(self, dataOut_channels, dataIn_channels,
                         order_din_index_for_dout):
        for out_i, (dataOut, order_s_for_m) in enumerate(
                zip(dataOut_channels, order_din_index_for_dout)):
            if order_s_for_m is None:
                connected_in = self.OUTPUTS[out_i]
                assert len(connected_in) == 1, connected_in
                connected_in = list(connected_in)[0]
                dataOut(dataIn_channels[connected_in],
                        exclude={dataOut.valid, dataOut.ready})
            else:
                cases = []
                for si, s in enumerate(dataIn_channels):
                    cases.append((si, dataOut(s, exclude={s.valid, s.ready})))

                Switch(order_s_for_m.data)\
                    .add_cases(cases)\
                    .Default(
                    s(None)
                    for s in dataOut._interfaces
                    if s not in {dataOut.valid, dataOut.ready}
                )
Пример #32
0
    def test_ifsInSwitch(self):
        n = self.n
        stT = HEnum('t_state', ["idle", "tsWait", "ts0Wait",
                                "ts1Wait", "lenExtr"])
        clk = n.sig('clk')
        rst = n.sig("rst")

        st = n.sig('st', stT, clk=clk, syncRst=rst, defVal=stT.idle)
        sd0 = n.sig('sd0')
        sd1 = n.sig('sd1')
        cntrlFifoVld = n.sig('ctrlFifoVld')
        cntrlFifoLast = n.sig('ctrlFifoLast')

        def tsWaitLogic():
            return If(sd0 & sd1,
                      c(stT.lenExtr, st)
                      ).Else(
                c(stT.ts1Wait, st)
            )
        obj = Switch(st)\
            .Case(stT.idle,
                  tsWaitLogic()
                  ).Case(stT.tsWait,
                         tsWaitLogic()
                         ).Case(stT.ts0Wait,
                                If(sd0,
                                   c(stT.lenExtr, st)
                                   ).Else(
                                    c(st, st)
                                )
                                ).Case(stT.ts1Wait,
                                       If(sd1,
                                          c(stT.lenExtr, st)
                                          ).Else(
                                           c(st, st)
                                       )
                                       ).Case(stT.lenExtr,
                                              If(cntrlFifoVld & cntrlFifoLast,
                                                 c(stT.idle, st)
                                                 ).Else(
                                                  c(st, st)
                                              )
                                              )

        cont, io_change = obj._try_reduce()
        self.assertFalse(io_change)
        self.assertEqual(len(cont), 1)
        cont = cont[0]
        tmpl = """
        CASE st IS
            WHEN idle =>
                IF (sd0 AND sd1) = '1' THEN
                    st_next <= lenExtr;
                ELSE
                    st_next <= ts1Wait;
                END IF;
            WHEN tsWait =>
                IF (sd0 AND sd1) = '1' THEN
                    st_next <= lenExtr;
                ELSE
                    st_next <= ts1Wait;
                END IF;
            WHEN ts0Wait =>
                IF sd0 = '1' THEN
                    st_next <= lenExtr;
                ELSE
                    st_next <= st;
                END IF;
            WHEN ts1Wait =>
                IF sd1 = '1' THEN
                    st_next <= lenExtr;
                ELSE
                    st_next <= st;
                END IF;
            WHEN OTHERS =>
                IF (ctrlFifoVld AND ctrlFifoLast) = '1' THEN
                    st_next <= idle;
                ELSE
                    st_next <= st;
                END IF;
        END CASE

        """
        self.strStructureCmp(cont, tmpl)