Beispiel #1
0
    def translate_addr_signal(self, mem_map, sig_in, sig_out):
        cases = []
        AW = sig_in._dtype.bit_length()

        for (offset_in, size, offset_out) in mem_map:
            in_is_aligned = offset_in % size == 0 and isPow2(size)
            out_is_aligned = offset_out % size == 0 and isPow2(size)
            if in_is_aligned:
                L = (size - 1).bit_length()
                en_sig = sig_in[:L]._eq(offset_in >> L)
                _sig_in = sig_in[L:]
                if out_is_aligned:
                    addr_drive = Concat(
                        Bits(AW - L).from_py(offset_out), _sig_in)
                else:
                    addr_drive = Concat(Bits(AW - L).from_py(0),
                                        _sig_in) + offset_out
            else:
                en_sig = inRange(sig_in, offset_in, offset_in + size)
                if offset_in == offset_out:
                    addr_drive = sig_in
                elif offset_in < offset_out:
                    addr_drive = sig_in + (offset_out - offset_in)
                else:
                    # offset_in > offset_out:
                    addr_drive = sig_in - (offset_in - offset_out)
            cases.append((en_sig, sig_out(addr_drive)))
        SwitchLogic(cases, default=sig_out(sig_in))
Beispiel #2
0
    def propagate(self, src_addr_sig, dst_addr_sig, dst_offset: int = 0):
        """
        :param src_addr_sig: input signal with address
        :param dst_addr_sig: output signal for address
        """
        src_addr_step, dst_addr_step = self.src_addr_step, self.dst_addr_step

        if src_addr_step != dst_addr_step:
            src_w = src_addr_sig._dtype.bit_length()
            dst_w = dst_addr_sig._dtype.bit_length()

            if src_addr_step > dst_addr_step:
                # extend src address
                assert src_w + self.align_bits <= dst_w, (
                    "Destination address space is smaller than required",
                    src_addr_sig, dst_addr_sig, src_w, self.align_bits, dst_w)
                padding = Bits(self.align_bits).from_py(0)
                src_addr_sig = Concat(src_addr_sig, padding)
            else:
                # cut src address
                assert src_w - self.align_bits <= dst_w, (
                    "Destination address space is smaller than required",
                    src_addr_sig, dst_addr_sig, src_w, self.align_bits, dst_w)
                src_addr_sig = src_addr_sig[:self.align_bits]

        # first extend then add if required to prevent value overflow
        src_addr_sig = src_addr_sig._reinterpret_cast(dst_addr_sig._dtype)
        if dst_offset != 0:
            src_addr_sig = src_addr_sig + dst_offset

        return dst_addr_sig(src_addr_sig)
Beispiel #3
0
    def connect_update_port(self, update: AxiCacheTagArrayUpdateIntf,
                            tag_mem_port_w: BramPort_withoutClk):
        update_tmp = self._reg("update_tmp",
                               HStruct(
                                   (update.addr._dtype, "addr"),
                                   (BIT, "delete"),
                                   (update.way_en._dtype, "way_en"),
                                   (BIT, "vld"),
                               ),
                               def_val={"vld": 0})
        update_tmp(update)
        tag, index, _ = self.parse_addr(update.addr)

        tag_mem_port_w.en(update.vld)
        tag_mem_port_w.addr(index)

        # construct the byte enable mask for various tag enable configurations
        # prepare write tag in every way but byte enable only requested ways
        tag_record = self.tag_record_t.from_py({
            "tag": tag,
            "valid": ~update.delete,
        })
        tag_record = tag_record._reinterpret_cast(
            Bits(self.tag_record_t.bit_length()))
        tag_mem_port_w.din(Concat(*(tag_record for _ in range(self.WAY_CNT))))
        tag_be_t = Bits(self.tag_record_t.bit_length() // 8)
        tag_en = tag_be_t.from_py(tag_be_t.all_mask())
        tag_not_en = tag_be_t.from_py(0)
        tag_mem_port_w.we(
            Concat(*reversed(
                [en._ternary(tag_en, tag_not_en) for en in update.way_en])))
        return update_tmp
Beispiel #4
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))
Beispiel #5
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)
Beispiel #6
0
    def _impl(self):
        w = self.port[0]
        ram_w = self.ram.port[0]

        # True if each byte of the mask is 0xff or 0x00
        we_bytes = list(iterBits(w.we, bitsInOne=8, fillup=True))
        # cut off padding
        we_for_we_bytes = []
        for last, b in iter_with_last(we_bytes):
            if last and self.MASK_PADDING_W:
                mask_rem_w = self.MASK_W % 8
                b = b[mask_rem_w:]
            we_for_we_bytes.append(b != 0)

        we_for_we_bytes = rename_signal(
            self,
            Concat(*[
                b | ~w.do_accumulate | w.do_overwrite
                for b in reversed(we_for_we_bytes)
            ]), "we_for_we_bytes")

        preload = self._reg("preload", def_val=0)
        If(w.en.vld, preload(~preload & w.do_accumulate & ~w.do_overwrite))
        w.en.rd(~w.do_accumulate | w.do_overwrite | preload)
        ram_w.addr(w.addr)
        ram_w.en(w.en.vld & (w.do_overwrite | ~w.do_accumulate | preload))
        ram_w.we(Concat(w.we, we_for_we_bytes))
        w_mask = w.we
        if self.MASK_PADDING_W:
            w_mask = Concat(Bits(self.MASK_PADDING_W).from_py(0), w_mask)

        is_first_read_port = True
        for ram_r, r in zip(self.ram.port[1:], self.port[1:]):
            if is_first_read_port:
                w_mask = preload._ternary(
                    w_mask | ram_r.dout[self.MASK_PADDING_W + self.MASK_W:],
                    w_mask)
                w_mask = rename_signal(self, w_mask, "w_mask")
                ram_w.din(Concat(w.din, w_mask))

                will_preload_for_accumulate = rename_signal(
                    self, w.en.vld & w.do_accumulate & ~w.do_overwrite,
                    "will_preload_for_accumulate")
                ram_r.addr(will_preload_for_accumulate._ternary(
                    w.addr, r.addr))
                ram_r.en(will_preload_for_accumulate | r.en.vld)
                # [TODO] check if r.en.rd is according to spec
                r.en.rd(~will_preload_for_accumulate | preload)
                is_first_read_port = False
            else:
                ram_r.addr(r.addr)
                ram_r.en(r.en.vld)
                r.en.rd(1)

            r.dout(ram_r.dout[:self.MASK_PADDING_W + self.MASK_W])
            r.dout_mask(ram_r.dout[self.MASK_W:])

        propagateClkRstn(self)
Beispiel #7
0
def expand_byte_mask_to_bit_mask(m):
    res = []
    for b in m:
        B = []
        for _ in range(8):
            B.append(b)

        res.append(Concat(*B))

    return Concat(*reversed(res))
Beispiel #8
0
    def insertLogic(self, ramW):
        In = self.insert

        if self.DATA_WIDTH:
            rec = Concat(In.key, In.data, In.vldFlag)
        else:
            rec = Concat(In.key, In.vldFlag)

        ramW.data(rec)
        ramW.addr(In.hash)
        StreamNode(masters=[In], slaves=[ramW]).sync()
Beispiel #9
0
    def matchHandler(self, mem, key: Handshaked, match_res: Handshaked):

        key_data = key.data
        if self.USE_VLD_BIT:
            key_data = Concat(key.data, BIT.from_py(1))

        out_one_hot = []
        for i in range(self.ITEMS):
            b = mem[i]._eq(key_data)
            out_one_hot.append(b)

        match_res.data(Concat(*reversed(out_one_hot)))
        StreamNode([key], [match_res]).sync()
Beispiel #10
0
    def delegate_to_children(self):
        MAX_DW = self.MAX_BLOCK_DATA_WIDTH
        DW = self.DATA_WIDTH

        for ports in zip(self.port, *[c.port for c in self.children]):
            dout = []
            p = ports[0]
            clk = getattr(p, "clk", None)

            for i, cp in enumerate(ports[1:]):
                cp.en(p.en)
                cp.addr(p.addr)
                if p.HAS_R:
                    dout.append(cp.dout)
                if p.HAS_W:
                    if p.HAS_BE:
                        cp.we(p.we[min((i + 1) * (MAX_DW // 8), DW // 8):i * (MAX_DW // 8)])
                    elif p.HAS_R:
                        cp.we(p.we)
                    cp.din(p.din[min((i + 1) * (MAX_DW), DW):i * (MAX_DW)])
                if clk is not None:
                    cp.clk(clk)

            if dout:
                p.dout(Concat(*reversed(dout)))

        clk = getattr(self, "clk", None)
        for c in self.children:
            c.clk(clk)
Beispiel #11
0
    def get_lru(self):
        """
        To find LRU, we can perform a depth-first-search starting from root,
        and traverse nodes in lower levels. If the node is 0, then we traverse the left sub-tree;
        otherwise, we traverse the right sub-tree. In the diagram above, the LRU is set 3.
        """
        # node_index: bits  rlu register
        node_paths = {}
        self._build_node_paths(node_paths, 0, tuple())
        # also number of levels of rlu tree
        bin_index_w = log2ceil(
            self.lru_reg_items(self.lru_regs._dtype.bit_length()))

        lru_index_bin = []
        # msb first in lru binary index
        for output_bit_i in range(bin_index_w):
            items_on_current_level = int(2**output_bit_i)
            current_level_offset = 2**output_bit_i - 1
            possible_paths = []
            for node_i in range(current_level_offset,
                                current_level_offset + items_on_current_level):
                p = node_paths[node_i]
                possible_paths.append(And(*p))
            lru_index_bin.append(Or(*possible_paths))

        # MSB was first so the result is in little endian MSB..LSB
        return Concat(*lru_index_bin)
Beispiel #12
0
    def _count_leading_recurse(cls, data_in: RtlSignal, bit_to_count: int):
        """
        Construct a balanced tree for counter of leading 0/1
        :atterntion: result is for

        """
        assert bit_to_count in (0, 1), bit_to_count
        in_width = data_in._dtype.bit_length()
        if in_width == 2:
            if bit_to_count == 0:
                return ~data_in[1]
            else:
                return data_in[1]
        else:
            assert in_width > 2, in_width
            lhs = data_in[:in_width // 2]
            rhs = data_in[in_width // 2:]
            if bit_to_count == 0:
                left_full = lhs._eq(0)
            else:
                left_full = lhs._eq(mask(lhs._dtype.bit_length()))

            in_ = left_full._ternary(rhs, lhs)
            half_count = cls._count_leading_recurse(in_, bit_to_count)
        return Concat(left_full, half_count)
Beispiel #13
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
Beispiel #14
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)
Beispiel #15
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
Beispiel #16
0
def shift_in_msb_first(reg, sig_in):
    """
    Shift data in to register, MSB first
    """
    w = reg._dtype.bit_length()
    w_in = sig_in._dtype.bit_length()
    return reg(Concat(reg[w - w_in:], sig_in))
Beispiel #17
0
    def _vec_to_signal(extra_strbs: Union[Tuple[int, bool], RtlSignal]):
        """
        :param extra_strbs: number of bits and padding flag or strb signal directly
        """
        res = []
        prev_len = 0
        prev_val = None
        for s in extra_strbs:
            if isinstance(s, Tuple):
                if prev_val is None:
                    prev_len, prev_val = s
                    assert prev_len > 0, prev_len
                elif prev_val is s[1]:
                    # try extend
                    prev_len += s[0]
                else:
                    StrbKeepStash._push_mask_vec(res, prev_len, prev_val)
                    prev_len, prev_val = s
            elif isinstance(s, (RtlSignal, Interface)):
                res.append(s)
                prev_len, prev_val = 0, None

        if prev_val is not None:
            StrbKeepStash._push_mask_vec(res, prev_len, prev_val)
        return Concat(*reversed(res))
    def dispatch_addr(self, id_to_use: RtlSignal, addr: RtlSignal,
                      a: Axi4_addr):
        """
        * if there is a valid item in buffer dispatch read request
        """

        a_ld = self._sig("a_ld")
        a_tmp = self._reg("ar_tmp",
                          HStruct(
                              (a.id._dtype, "id"),
                              (addr._dtype, "addr"),
                              (BIT, "vld"),
                          ),
                          def_val={"vld": 0})

        If(a_ld, a_tmp.id(id_to_use), a_tmp.addr(addr),
           a_tmp.vld(1)).Else(a_tmp.vld(a_tmp.vld & ~a.ready))
        a.id(a_tmp.id)
        a.addr(Concat(a_tmp.addr,
                      Bits(self.CACHE_LINE_OFFSET_BITS).from_py(0)))

        a.len(self.BUS_WORDS_IN_CACHE_LINE - 1)
        a.burst(BURST_INCR)
        a.prot(PROT_DEFAULT)
        a.size(BYTES_IN_TRANS(self.DATA_WIDTH // 8))
        a.lock(LOCK_DEFAULT)
        a.cache(CACHE_DEFAULT)
        a.qos(QOS_DEFAULT)
        a.valid(a_tmp.vld)

        return a_ld
Beispiel #19
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])
Beispiel #20
0
    def deparse_addr(self, tag, index,
                     offset) -> Tuple[RtlSignal, RtlSignal, RtlSignal]:
        if isinstance(offset, int):
            offset = Bits(self.OFFSET_W).from_py(offset)

        if isinstance(index, int):
            index = Bits(self.INDEX_W).from_py(index)

        return Concat(tag, index, offset)
Beispiel #21
0
    def writeHandler(self, mem):
        w = self.write
        w.rd(1)

        key_data = w.data
        if self.USE_VLD_BIT:
            key_data = Concat(w.data, w.vld_flag)

        If(self.clk._onRisingEdge() & w.vld, mem[w.addr](key_data))
Beispiel #22
0
def extend_to_width_multiple_of_8(sig):
    """
    make width of signal modulo 8 equal to 0
    """
    w = sig._dtype.bit_length()
    cosest_multiple_of_8 = ceil((w // 8) / 8) * 8
    if cosest_multiple_of_8 == w:
        return sig
    else:
        return Concat(Bits(cosest_multiple_of_8 - w).from_py(0), sig)
Beispiel #23
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()
Beispiel #24
0
    def _impl(self):
        # prepare constants and bit arrays for inputs
        DW = int(self.DATA_WIDTH)
        polyBits, PW = CrcComb.parsePoly(self.POLY, self.POLY_WIDTH)

        XOROUT = int(self.XOROUT)
        finBits = [hBit(selectBit(XOROUT, i)) for i in range(PW)]

        # rename "dataIn_data" to "d" to make code shorter
        _d = self.wrapWithName(self.dataIn.data, "d")
        inBits = list(iterBits(_d))
        if not self.IN_IS_BIGENDIAN:
            inBits = reversedEndianity(inBits)

        state = self._reg("c", Bits(self.POLY_WIDTH), self.INIT)
        stateBits = list(iterBits(state))

        # build xor tree for CRC computation
        crcMatrix = CrcComb.buildCrcXorMatrix(DW, polyBits)
        res = CrcComb.applyCrcXorMatrix(crcMatrix, inBits, stateBits,
                                        bool(self.REFIN))

        # next state logic
        # wrap crc next signals to separate signal to have nice code
        stateNext = []
        for i, crcbit in enumerate(res):
            b = self.wrapWithName(crcbit, "crc_%d" % i)
            stateNext.append(b)

        If(
            self.dataIn.vld,
            # regNext is in format 0 ... N, we need to reverse it to litle
            # endian
            state(Concat(*reversed(stateNext))))

        # output connection
        if self.REFOUT:
            finBits = reversed(finBits)
            self.dataOut(
                Concat(*[rb ^ fb for rb, fb in zip(iterBits(state), finBits)]))
        else:
            self.dataOut(state ^ Concat(*finBits))
Beispiel #25
0
    def connectPhyout(self, segfaultFlag):
        phyAddrBase = self.lvl2get.item
        pageOffset = self.pageOffsetFifo.dataOut

        segfault = segfaultFlag | phyAddrBase.data[0]._eq(FLAG_INVALID)
        StreamNode(masters=[phyAddrBase, pageOffset],
                   slaves=[self.physOut],
                   extraConds={self.physOut:~segfault}).sync()

        self.physOut.data(Concat(phyAddrBase.data[:self.PAGE_OFFSET_WIDTH],
                                 pageOffset.data))
Beispiel #26
0
def binToOneHot(sig, en=1):
    try:
        _en = int(en)
    except:
        _en = None

    res = Concat(*reversed(list(sig._eq(i) for i in range(2 ** sig._dtype.bit_length()))))
    if _en == 1:
        return res
    else:
        return en._ternary(res, res._dtype.from_py(0))
Beispiel #27
0
    def _impl(self):
        propagateClkRstn(self)
        dIn = AxiSBuilder(self, self.dataIn).buff().end

        sb = self.sizesBuff
        db = self.dataBuff

        wordCntr = self._reg("wordCntr",
                             Bits(log2ceil(self.MAX_LEN) + 1),
                             def_val=0)

        overflow = wordCntr._eq(self.MAX_LEN)
        last = dIn.last | overflow
        If(
            StreamNode(masters=[dIn], slaves=[sb.dataIn, db.dataIn]).ack(),
            If(last, wordCntr(0)).Else(wordCntr(wordCntr + 1)))

        length = self._sig("length", wordCntr._dtype)
        BYTE_CNT = dIn.data._dtype.bit_length() // 8
        if dIn.USE_STRB:
            # compress strb mask as binary number
            rem = self._sig("rem", Bits(log2ceil(BYTE_CNT)))

            SwitchLogic(cases=[(dIn.strb[i],
                                rem(0 if i == BYTE_CNT - 1 else i + 1))
                               for i in reversed(range(BYTE_CNT))],
                        default=[
                            rem(0),
                        ])
            if self.EXPORT_ALIGNMENT_ERROR:
                errorAlignment = self._reg("errorAlignment_reg", def_val=0)
                self.errorAlignment(errorAlignment)
                If(dIn.valid & (dIn.strb != mask(BYTE_CNT)) & ~dIn.last,
                   errorAlignment(1))

            If(last & (dIn.strb != mask(BYTE_CNT)),
               length(wordCntr)).Else(length(wordCntr + 1))
        else:
            length(wordCntr + 1)
            rem = Bits(log2ceil(BYTE_CNT)).from_py(0)

        sb.dataIn.data(Concat(length, rem))

        db.dataIn(dIn, exclude=[dIn.valid, dIn.ready, dIn.last])
        db.dataIn.last(last)

        StreamNode(masters=[dIn],
                   slaves=[sb.dataIn, db.dataIn],
                   extraConds={
                       sb.dataIn: last
                   }).sync()

        self.sizes(sb.dataOut)
        self.dataOut(db.dataOut)
Beispiel #28
0
 def applyShift(sh):
     if sh == 0 and wInfo.SHIFT_OPTIONS[0] == 0:
         return [
             w.data(wIn.data),
             w.strb(wIn.strb),
         ]
     else:
         rem_w = self.DATA_WIDTH - sh
         return [
             # wIn.data starts on 0 we need to shift it sh bits
             # in first word the prefix is invalid, in rest of the frames it is taken from
             # previous data
             If(
                 waitForShift,
                 w.data(
                     Concat(
                         Bits(rem_w).from_py(None),
                         prevData.data[:rem_w])),
             ).Else(
                 w.data(
                     Concat(wIn.data[rem_w:],
                            prevData.data[:rem_w])), ),
             If(
                 waitForShift,
                 # wait until remainder of previous data is send
                 w.strb(
                     Concat(
                         Bits(rem_w // 8).from_py(0),
                         prevData.strb[:rem_w // 8])),
             ).Elif(
                 isFirst,
                 # ignore previous data
                 w.strb(
                     Concat(wIn.strb[rem_w // 8:],
                            Bits(sh // 8).from_py(0))),
             ).Else(
                 # take what is left from prev data and append from wIn
                 w.strb(
                     Concat(wIn.strb[rem_w // 8:],
                            prevData.strb[:rem_w // 8])), )
         ]
Beispiel #29
0
    def connectRegisters(self, st, onoff, baseAddr):
        """
        connection of axilite registers
        """
        idle = st._eq(st._dtype.fullIdle)
        regs = self.regsConventor.decoded
        regs.control.din(Concat(onoff, idle, vec(0, self.DATA_WIDTH - 2)))

        If(regs.control.dout.vld, onoff(regs.control.dout.data[0]))

        c(baseAddr, regs.baseAddr.din)
        If(regs.baseAddr.dout.vld, baseAddr(regs.baseAddr.dout.data))
Beispiel #30
0
    def _impl(self):
        din = self.din

        internReg = [self._sig("internReg", BIT, defVal=False) for _ in range(2)]

        If(self.clk._onRisingEdge(),
           internReg[0](din),
        )
        If(self.clk._onFallingEdge(),
           internReg[1](din),
        )
        self.dout(Concat(*internReg))