Пример #1
0
    def HdlType_bits(cls, typ: Bits, ctx, declaration=False):
        isVector = typ.force_vector or typ.bit_length() > 1
        nameBuff = []
        sigType = ctx.signalType
        if sigType is SIGNAL_TYPE.PORT:
            pass
        elif sigType is SIGNAL_TYPE.REG:
            nameBuff.append("reg")
        elif sigType is SIGNAL_TYPE.WIRE:
            nameBuff.append("wire")
        else:
            raise NotImplementedError()

        if typ.signed:
            nameBuff.append("signed")

        w = typ.bit_length()
        if not isVector:
            pass
        elif isinstance(w, int):
            nameBuff.append("[%d:0]" % (w - 1))
        else:
            nameBuff.append("[%s- 1:0]" % cls.Value(w, ctx))

        return " ".join(nameBuff)
Пример #2
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        isVector = typ.force_vector or typ.bit_length() > 1
        sigType = self.signalType

        if typ == INT:
            t = HdlValueId("int", obj=int)
        elif sigType is SIGNAL_TYPE.PORT_WIRE:
            t = HdlTypeAuto
        elif sigType is SIGNAL_TYPE.REG or sigType is SIGNAL_TYPE.PORT_REG:
            t = HdlValueId("reg", obj=LanguageKeyword())
        elif sigType is SIGNAL_TYPE.WIRE:
            t = HdlValueId("wire", obj=LanguageKeyword())
        else:
            raise ValueError(sigType)

        if typ.signed is None:
            is_signed = None
        else:
            is_signed = self.as_hdl_int(int(typ.signed))

        if isVector:
            w = typ.bit_length()
            assert isinstance(w, int) or (isinstance(w, RtlSignal)
                                          and w._const), w
            w = hdl_downto(self.as_hdl(w - 1), self.as_hdl_int(0))
        else:
            w = None

        return HdlOp(HdlOpType.PARAMETRIZATION, [t, w, is_signed])
Пример #3
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()
        if typ == BOOL:
            return self.BOOLEAN
        if typ == INT:
            return self.INTEGER

        bitLength = typ.bit_length()
        w = typ.bit_length()
        isVector = typ.force_vector or bitLength > 1

        if typ.signed is None:
            if isVector:
                name = self.STD_LOGIC_VECTOR
            else:
                return self.STD_LOGIC
        elif typ.signed:
            name = self.SIGNED
        else:
            name = self.UNSIGNED

        return HdlOp(HdlOpType.CALL, [
            name,
            HdlOp(HdlOpType.DOWNTO, [
                self.as_hdl(w - 1),
                self.as_hdl_int(0)
            ])])
Пример #4
0
def makeTestbenchTemplate(unit: Unit, name: str=None):
    """
    :param unit: synthesized unit
    :return: (entity, arch, context) of testbench
    """
    if name is None:
        name = unit._name + "_tb"

    entity = Entity(name)
    arch = Architecture(entity)

    arch.components.append(unit._entity)
    arch.componentInstances.append(unit._entity)

    nl = RtlNetlist()
    ctx = {}
    for p in unit._entity.ports:
        t = p._dtype
        if isinstance(t, Bits) and not t == BIT:
            t = Bits(t.bit_length(), signed=t.signed,
                     forceVector=t.forceVector)
        s = RtlSignal(nl, p.name, t, t.fromPy(0))
        ctx[p._interface] = s
        p.connectSig(s)

    arch.variables.extend(ctx.values())

    return entity, arch, ctx
Пример #5
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()
        if typ == BOOL:
            return self.BOOL
        if typ == INT:
            return self.INT

        w = typ.bit_length()
        assert isinstance(w, int), w

        def add_kw(name, val):
            kw = hdl_map_asoc(HdlValueId(name),
                              HdlValueInt(val, None, None))
            args.append(kw)

        args = [HdlValueInt(w, None, None)]
        if typ.signed is not BITS_DEFAUTL_SIGNED:
            add_kw("signed", typ.signed)
        if typ.force_vector is not BITS_DEFAUTL_FORCEVECTOR and w <= 1:
            add_kw("force_vector", typ.force_vector)
        if typ.negated is not BITS_DEFAUTL_NEGATED:
            add_kw("negated", typ.negated)

        return hdl_call(self.BITS, args)
Пример #6
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        assert not declaration
        w = typ.bit_length()
        if isinstance(w, int):
            pass
        else:
            w = int(w)

        return hdl_call(self.BITS3T, [
            HdlValueInt(w, None, None),
            HdlValueInt(int(bool(typ.signed)), None, None)
        ])
Пример #7
0
    def HdlType_bits(cls, typ: Bits, ctx, declaration=False):
        disableRange = False
        bitLength = typ.bit_length()
        w = typ.bit_length()
        isVector = typ.force_vector or bitLength > 1

        if typ.signed is None:
            if isVector:
                name = 'STD_LOGIC_VECTOR'
            else:
                return 'STD_LOGIC'
        elif typ.signed:
            name = "SIGNED"
        else:
            name = 'UNSIGNED'

        if disableRange:
            constr = ""
        else:
            constr = "(%d DOWNTO 0)" % (w - 1)

        return name + constr
Пример #8
0
    def HdlType_bits(cls, typ: Bits, ctx, declaration=False):
        if declaration:
            raise NotImplementedError()
        w = typ.bit_length()
        assert isinstance(w, int), w

        iItems = ["%d" % w]
        if typ.signed is not BITS_DEFAUTL_SIGNED:
            iItems.append("signed=%r" % typ.signed)
        if typ.force_vector is not BITS_DEFAUTL_FORCEVECTOR and w <= 1:
            iItems.append("force_vector=%r" % typ.force_vector)
        if typ.negated is not BITS_DEFAUTL_NEGATED:
            iItems.append("negated=%r" % typ.negated)

        return "Bits(%s)" % (", ".join(iItems))
Пример #9
0
    def as_hdl_HdlType_bits(self, typ: Bits, declaration=False):
        if declaration:
            raise NotImplementedError()

        w = typ.bit_length()

        if w <= 64:
            if typ.signed:
                typeBaseName = self.sc_int
            else:
                typeBaseName = self.sc_uint
        else:
            if typ.signed:
                typeBaseName = self.sc_bigint
            else:
                typeBaseName = self.sc_biguint

        t = HdlOp(HdlOpType.PARAMETRIZATION,
                  [typeBaseName, self.as_hdl_int(w)])
        if self.signalType == SIGNAL_TYPE.WIRE:
            t = HdlOp(HdlOpType.PARAMETRIZATION, [self.sc_signal, t])
        return t
Пример #10
0
    def _impl(self):
        S_ADDR_STEP = self.S_ADDR_STEP
        assert S_ADDR_STEP >= self.S_DATA_WIDTH, \
            (S_ADDR_STEP, self.S_DATA_WIDTH)

        axi = self.m
        # if 2 * self.S_ADDR_STEP <= self.DATA_WIDTH:
        #    # multiple items can be in a single axi word
        #    # require the transaction alignment
        #    axi_resize = AxiResize(axi.__class__)
        #    axi_resize._updateParamsFrom(axi)
        #    axi_resize.DATA_WIDTH = self.S_ADDR_STEP
        #    axi_resize.OUT_DATA_WIDTH = axi.DATA_WIDTH
        #    axi_resize.OUT_ADDR_WIDTH = axi.ADDR_WIDTH
        #    self.axi_resize = axi_resize
        #    axi(axi_resize.m)
        #    axi = axi_resize.s

        # add extra register on axi
        b = AxiBuff(axi.__class__)
        b._updateParamsFrom(axi)
        self.axi_buff = b
        axi(b.m)
        axi = b.s

        cntr_t = Bits(log2ceil(self.MAX_TRANS_OVERLAP), signed=False)
        CNTR_MAX = mask(cntr_t.bit_length())

        if self.HAS_R:
            s_r = self.s_r
            r_cntr = self._reg("r_cntr", cntr_t, def_val=0)
            self.connect_r(s_r, axi, r_cntr, CNTR_MAX, self.in_axi_t)

        if self.HAS_W:
            s_w = self.s_w
            w_cntr = self._reg("w_cntr", cntr_t, def_val=0)
            self.connect_w(s_w, axi, w_cntr, CNTR_MAX, self.in_axi_t)

        propagateClkRstn(self)
Пример #11
0
class FifoArray(Unit):
    """
    This component is an array of list nodes, which can be used to emulate multiple FIFOs.
    The memory is shared and the number of lists stored in this array is limited only by memory.

    Corresponds to data structure:

    .. code-block:: cpp

        // note that in implementation each part of struct item is stored in separate array
        struct item {
          value_t value;
          item * next;
          bool valid;
          bool last;
        };

        item items[ITEMS];

    :note: The insert_addr is used to pop from specific list.
        The list can be read only from it's head in FIFO order manner.
        Item is last if it's next pointer points on this item.
    :note: DistRAM implementation.
    :note: The pop address is not checked
        it is possible to pop from wrong list if address is specified incorrectly

    .. hwt-autodoc::
    """
    def _config(self):
        self.ITEMS = Param(4)
        self.DATA_WIDTH = Param(8)

    def _declr(self):
        assert self.ITEMS > 1, self.ITEMS
        self.addr_t = Bits(log2ceil(self.ITEMS - 1), signed=False)
        self.value_t = Bits(self.DATA_WIDTH)

        addClkRstn(self)
        self.insert = FifoArrayInsertInterface()

        self.pop = FifoArrayPopInterface()._m()
        for i in [self.insert, self.pop]:
            i.ADDR_WIDTH = self.addr_t.bit_length()
            i.DATA_WIDTH = self.value_t.bit_length()

    def _impl(self):
        addr_t = self.addr_t
        value_t = self.value_t
        item_mask_t = Bits(self.ITEMS)

        # bitmap used to quickly detect position of an empty node
        item_valid = self._reg("item_valid", item_mask_t, def_val=0)
        item_last = self._reg("item_last", item_mask_t, def_val=0)
        # an address on where next item should be inserted
        insert_addr_next = self._reg("insert_addr_next", addr_t, def_val=0)
        insert_addr_next(
            oneHotToBin(
                self,
                rename_signal(
                    self, ~item_valid.next,
                    "item_become_invalid")))  # get index of first non valid

        pop = self.pop
        insert = self.insert

        insert.addr_ret(insert_addr_next)
        insert.rd(item_valid != mask(self.ITEMS))

        pop_one_hot = rename_signal(self,
                                    binToOneHot(pop.addr, en=pop.vld & pop.rd),
                                    "pop_one_hot")
        insert_one_hot = rename_signal(
            self, binToOneHot(insert_addr_next, en=insert.vld & insert.rd),
            "insert_one_hot")
        insert_parent_one_hot = rename_signal(
            self,
            binToOneHot(insert.addr,
                        en=insert.vld & insert.rd & insert.append),
            "insert_parent_one_hot")

        item_valid((item_valid & ~pop_one_hot) | insert_one_hot)
        item_last((item_last & ~insert_parent_one_hot) | insert_one_hot)

        values = self._sig("values", value_t[self.ITEMS])
        next_ptrs = self._sig("next_ptrs", addr_t[self.ITEMS])

        If(
            self.clk._onRisingEdge(),
            If(
                insert.vld & insert.rd,
                next_ptrs[insert.addr]
                (insert_addr_next),  # append behind parent node at insert_ptr
                values[insert_addr_next](insert.data),
            ))
        pop.data(values[pop.addr])
        pop.addr_next(next_ptrs[pop.addr])
        pop.last(item_last[pop.addr] & item_valid[pop.addr])
        pop.vld(item_valid != 0)
Пример #12
0
 def getLen_t(self):
     len_t = self.driver.req.len._dtype
     if not self.isAlwaysAligned():
         len_t = Bits(len_t.bit_length() + 1, signed=False)
     return len_t
Пример #13
0
    def _impl(self):
        DEPTH = self.DEPTH

        index_t = Bits(log2ceil(DEPTH), signed=False)
        s = self._sig
        r = self._reg

        mem = self.mem = s("memory", Bits(self.DATA_WIDTH)[self.DEPTH + 1])
        # write pointer which is seen by reader
        wr_ptr = r("wr_ptr", index_t, 0)
        # read pointer which is used by reader and can be potentially
        # reseted to a rd_ptr value (copy command) or can update rd_ptr (non-copy command)
        rd_ptr_tmp = r("rd_ptr_tmp", index_t, 0)
        rd_ptr = r("rd_ptr", index_t, 0)
        MAX_DEPTH = DEPTH - 1
        assert MAX_DEPTH.bit_length() == index_t.bit_length(), (MAX_DEPTH,
                                                                index_t)

        dout = self.dataOut
        din = self.dataIn

        fifo_write = s("fifo_write")
        fifo_read = s("fifo_read")
        frame_copy = self.dataOut_copy_frame

        # Update Tail pointer as needed
        If(
            fifo_read,
            If(
                frame_copy.vld & frame_copy.data,
                If(rd_ptr._eq(MAX_DEPTH),
                   rd_ptr_tmp(0)).Else(rd_ptr_tmp(rd_ptr + 1))).Elif(
                       rd_ptr_tmp._eq(MAX_DEPTH),
                       rd_ptr_tmp(0)).Else(rd_ptr_tmp(rd_ptr_tmp + 1)),
        )
        If(
            frame_copy.vld & ~frame_copy.data,
            # jump to next frame
            rd_ptr(rd_ptr_tmp)
            # If(rd_ptr_tmp._eq(MAX_DEPTH),
            #    rd_ptr(0)
            # ).Else(
            #    rd_ptr(rd_ptr_tmp + 1)
            # )
        )

        wr_ptr_next = self._sig("wr_ptr_next", index_t)
        If(wr_ptr._eq(MAX_DEPTH), wr_ptr_next(0)).Else(wr_ptr_next(wr_ptr + 1))
        # Increment Head pointer as needed
        If(fifo_write, wr_ptr(wr_ptr_next))

        If(
            self.clk._onRisingEdge(),
            If(
                fifo_write,
                # Write Data to Memory
                mem[wr_ptr](din.data)))

        fifo_read(dout.en & (
            (wr_ptr != rd_ptr_tmp) | (frame_copy.vld & frame_copy.data)))
        read_addr_tmp = rename_signal(
            self,
            (frame_copy.vld & frame_copy.data)._ternary(rd_ptr, rd_ptr_tmp),
            "read_addr_tmp")
        If(
            self.clk._onRisingEdge(),
            If(
                fifo_read,
                # Update data output
                dout.data(mem[read_addr_tmp])))

        fifo_write(din.en & (wr_ptr_next != rd_ptr))

        # Update Empty and Full flags
        din.wait(wr_ptr_next._eq(rd_ptr))
        If(frame_copy.vld & frame_copy.data,
           dout.wait(0)).Else(dout.wait((wr_ptr._eq(rd_ptr_tmp))))