Пример #1
0
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return self.as_hdl_cond(ops[0], True)
            else:
                op0 = self.as_hdl_cond(ops[0], True)
                op1 = self.as_hdl_operand(ops[1], 1, op)
                op2 = self.as_hdl_operand(ops[2], 2, op)
                return HdlOp(HdlOpType.TERNARY, [op0, op1, op2])
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            raise UnsupportedEventOpErr()
        elif o in [AllOps.BitsAsUnsigned, AllOps.BitsAsVec, AllOps.BitsAsSigned]:
            op0, = ops
            do_cast = bool(op0._dtype.signed) != bool(op.result._dtype.signed)

            op_hdl = self.as_hdl_operand(op0, 0, op)
            if do_cast:
                if bool(op0._dtype.signed):
                    cast = self.SIGNED
                else:
                    cast = self.UNSIGNED
                return hdl_call(cast, [op_hdl, ])
            else:
                return op_hdl
        else:
            _o = self.op_transl_dict[o]
            return HdlOp(_o, [self.as_hdl_operand(o2, i, op)
                              for i, o2 in enumerate(ops)])
Пример #2
0
    def _impl(self):
        DW = int(self.DATA_WIDTH)
        polyBits, PW = self.parsePoly(self.POLY, self.POLY_WIDTH)
        XOROUT = int(self.XOROUT)
        _INIT = int(self.INIT)
        initBits = [BIT.from_py(get_bit(_INIT, i)) for i in range(PW)]
        finBits = [BIT.from_py(get_bit(XOROUT, i)) for i in range(PW)]

        # rename to have shorter code
        _inD = self._sig("d", self.dataIn._dtype)
        _inD(self.dataIn)
        inBits = list(iterBits(_inD))

        if not self.IN_IS_BIGENDIAN:
            # we need to process lower byte first
            inBits = bit_list_reversed_endianity(inBits, extend=False)

        crcMatrix = self.buildCrcXorMatrix(DW, polyBits)
        res = self.applyCrcXorMatrix(crcMatrix, inBits, initBits,
                                     bool(self.REFIN))

        if self.REFOUT:
            res = list(reversed(res))
            finBits = bit_list_reversed_bits_in_bytes(finBits, extend=False)

        outBits = iterBits(self.dataOut)
        for ob, b, fb in zip(outBits, res, finBits):
            ob(b ^ fb)
Пример #3
0
    def _impl(self):
        propagateClkRstn(self)
        r = self._reg

        START_BIT = BIT.from_py(0)
        STOP_BIT = BIT.from_py(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", def_val=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(BIT.from_py(1)._concat(data[:1])),
               If(
                   last,
                   en(0),
               ))
        din.rd(~en)

        txd = r("reg_txd", def_val=1)
        If(tick & en, txd(data[0]))
        self.txd(txd)
Пример #4
0
 def _config(self):
     self.ACASCREG = Param(1)
     self.ADREG = Param(1)
     self.ALUMODEREG = Param(1)
     self.AREG = Param(1)
     self.AUTORESET_PATDET = Param("NO_RESET")
     self.A_INPUT = Param("DIRECT")
     self.BCASCREG = Param(1)
     self.BREG = Param(1)
     self.B_INPUT = Param("DIRECT")
     self.CARRYINREG = Param(1)
     self.CARRYINSELREG = Param(1)
     self.CREG = Param(1)
     self.DREG = Param(1)
     self.INMODEREG = Param(1)
     self.IS_ALUMODE_INVERTED = Param(Bits(4).from_py(0b0000))
     self.IS_CARRYIN_INVERTED = Param(BIT.from_py(0b0))
     self.IS_CLK_INVERTED = Param(BIT.from_py(0b0))
     self.IS_INMODE_INVERTED = Param(Bits(5).from_py(0b00000))
     self.IS_OPMODE_INVERTED = Param(Bits(7).from_py(0b0000000))
     self.MASK = Param(Bits(48).from_py(0x3fffffffffff))
     self.MREG = Param(1)
     self.OPMODEREG = Param(1)
     self.PATTERN = Param(Bits(48).from_py(0x000000000000))
     self.PREG = Param(1)
     self.SEL_MASK = Param("MASK")
     self.SEL_PATTERN = Param("PATTERN")
     self.USE_DPORT = Param("FALSE")
     self.USE_MULT = Param("MULTIPLY")
     self.USE_PATTERN_DETECT = Param("NO_PATDET")
     self.USE_SIMD = Param("ONE48")
Пример #5
0
    def as_hdl_Operator(self, op: Operator):
        ops = op.operands
        o = op.operator

        if o == AllOps.EQ:
            op0 = self.as_hdl_Value(ops[0])
            op1 = self.as_hdl_Value(ops[1])
            return hdl_call(hdl_getattr(op0, "_eq"), [
                op1,
            ])
        elif o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return self.as_hdl_cond(ops[0], True)
            else:
                op0 = self.as_hdl_cond(ops[0], True)
                op1 = self.as_hdl_Value(ops[1])
                op2 = self.as_hdl_Value(ops[2])
                return hdl_call(hdl_getattr(op0, "_ternary"), [op1, op2])
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            if o == AllOps.RISING_EDGE:
                fn = "_onRisingEdge"
            else:
                fn = "_onFallingEdge"
            op0 = self.as_hdl_Value(ops[0])
            # pop .val
            op0 = op0.ops[0]
            return hdl_call(hdl_getattr(op0, fn), [])
        elif o in [
                AllOps.BitsAsUnsigned, AllOps.BitsAsVec, AllOps.BitsAsSigned
        ]:
            op0, = ops
            do_cast = bool(op0._dtype.signed) != bool(op.result._dtype.signed)

            op_hdl = self.as_hdl_Value(op0)
            if do_cast:
                if bool(op0._dtype.signed):
                    sign = self.TRUE
                else:
                    sign = self.FALSE
                    # cast_sign()
                return hdl_call(hdl_getattr(op_hdl, "cast_sign"), [
                    sign,
                ])
            else:
                return op_hdl
        elif o == AllOps.CONCAT:
            return hdl_call(hdl_getattr(self.as_hdl_Value(ops[0]), "_concat"),
                            [
                                self.as_hdl_Value(ops[1]),
                            ])
        elif o == AllOps.EQ:
            return hdl_call(hdl_getattr(self.as_hdl_Value(ops[0]), "_eq"), [
                self.as_hdl_Value(ops[1]),
            ])
        else:
            o = self.op_transl_dict[o]
            return HdlOp(o, [self.as_hdl_Value(o2) for o2 in ops])
Пример #6
0
    def _config(self):
        self.BANDWIDTH = Param("OPTIMIZED")
        self.CLKFBOUT_MULT_F = Param(5.0)
        self.CLKFBOUT_PHASE = Param(0.0)
        self.CLKFBOUT_USE_FINE_PS = Param(False)
        self.CLKIN1_PERIOD = Param(0.0)
        self.CLKIN2_PERIOD = Param(0.0)

        self.CLKOUT0_DIVIDE_F = Param(1.0)
        self.CLKOUT0_DUTY_CYCLE = Param(0.5)
        self.CLKOUT0_PHASE = Param(0.0)
        self.CLKOUT0_USE_FINE_PS = Param(False)

        self.CLKOUT1_DIVIDE = Param(1)
        self.CLKOUT1_DUTY_CYCLE = Param(0.5)
        self.CLKOUT1_PHASE = Param(0.0)
        self.CLKOUT1_USE_FINE_PS = Param(False)

        self.CLKOUT2_DIVIDE = Param(1)
        self.CLKOUT2_DUTY_CYCLE = Param(0.5)
        self.CLKOUT2_PHASE = Param(0.0)
        self.CLKOUT2_USE_FINE_PS = Param(False)

        self.CLKOUT3_DIVIDE = Param(1)
        self.CLKOUT3_DUTY_CYCLE = Param(0.5)
        self.CLKOUT3_PHASE = Param(0.0)
        self.CLKOUT3_USE_FINE_PS = Param(False)

        self.CLKOUT4_CASCADE = Param(False)
        self.CLKOUT4_DIVIDE = Param(1)
        self.CLKOUT4_DUTY_CYCLE = Param(0.5)
        self.CLKOUT4_PHASE = Param(0.0)
        self.CLKOUT4_USE_FINE_PS = Param(False)

        self.CLKOUT5_DIVIDE = Param(1)
        self.CLKOUT5_DUTY_CYCLE = Param(0.5)
        self.CLKOUT5_PHASE = Param(0.0)
        self.CLKOUT5_USE_FINE_PS = Param(False)

        self.CLKOUT6_DIVIDE = Param(1)
        self.CLKOUT6_DUTY_CYCLE = Param(0.5)
        self.CLKOUT6_PHASE = Param(0.0)
        self.CLKOUT6_USE_FINE_PS = Param(False)

        self.COMPENSATION = Param("ZHOLD")
        self.DIVCLK_DIVIDE = Param(1)
        self.IS_CLKINSEL_INVERTED = Param(BIT.from_py(0b0))
        self.IS_PSEN_INVERTED = Param(BIT.from_py(0b0))
        self.IS_PSINCDEC_INVERTED = Param(BIT.from_py(0b0))
        self.IS_PWRDWN_INVERTED = Param(BIT.from_py(0b0))
        self.IS_RST_INVERTED = Param(BIT.from_py(0b0))
        self.REF_JITTER1 = Param(0.01)
        self.REF_JITTER2 = Param(0.01)
        self.SS_EN = Param(False)
        self.SS_MOD_PERIOD = Param(10000)
        self.SS_MODE = Param("CENTER_HIGH")
        self.STARTUP_WAIT = Param(False)
Пример #7
0
 def __init__(self, word_index: Optional[RtlSignal], word_index_start: int):
     self.word_index = word_index
     self.members = []
     self.word_range_min = word_index_start
     self.word_range_max = word_index_start
     self.others_first = []
     self.others_last = []
     self.vld_first = BIT.from_py(0)
     self.vld_last = BIT.from_py(0)
Пример #8
0
    def as_hdl_Assignment(self, a: Assignment):
        _dst = dst = a.dst
        assert isinstance(dst, SignalItem)

        if a.indexes is not None:
            for i in a.indexes:
                if isinstance(i, SliceVal):
                    i = i.__copy__()
                dst = dst[i]

        src_t = a.src._dtype
        dst_t = dst._dtype
        correct = False
        src = a.src
        if dst_t == src_t:
            correct = True
        else:
            src = a.src
            if (isinstance(dst_t, Bits) and isinstance(src_t, Bits)):
                # std_logic <->  std_logic_vector(0 downto 0) auto conversions
                if dst_t.bit_length() == src_t.bit_length() == 1:
                    if dst_t.force_vector and not src_t.force_vector:
                        dst = dst[0]
                        correct = True
                    elif not dst_t.force_vector and src_t.force_vector:
                        src = src[0]
                        correct = True
                    elif src_t == BOOL:
                        src = src._ternary(BIT.from_py(1), BIT.from_py(0))
                        correct = True
                elif not src_t.strict_width:
                    if isinstance(src, HValue):
                        src = copy(src)
                        if a.indexes:
                            raise NotImplementedError()

                        src._dtype = dst_t
                        correct = True
                    else:
                        raise NotImplementedError()
                        pass

        if correct:
            src = self.as_hdl(src)
            hdl_a = HdlStmAssign(src, self.as_hdl(dst))
            hdl_a.is_blocking = _dst.virtual_only
            return hdl_a

        raise SerializerException(
            f"{dst} = {a.src}  is not valid assignment\n"
            f" because types are different ({dst._dtype}; {a.src._dtype})")
Пример #9
0
    def connectParts(self, allOutNodes: ListOfOutNodeInfos, words,
                     wordIndex: Optional[RtlSignal]):
        """
        Create main datamux from dataIn to dataOut
        """
        for currentWordIndex, transParts, _ in words:
            # each word index is used and there may be TransParts which are
            # representation of padding
            outNondes = ListOfOutNodeInfos()
            for part in transParts:
                self.connectPart(outNondes, part, BIT.from_py(1),
                                 BIT.from_py(1), wordIndex, currentWordIndex)

            allOutNodes.addWord(currentWordIndex, outNondes)
Пример #10
0
    def isSelectedLogic(self, din_vlds, dout_rd, selectedOneHot):
        """
        Resolve isSelected signal flags for each input, when isSelected flag
        signal is 1 it means input has clearance to make transaction
        """
        assert din_vlds
        if len(din_vlds) == 1:
            isSelectedFlags = [
                BIT.from_py(1),
            ]
            if selectedOneHot is not None:
                selectedOneHot.data(1)
        else:
            priority = self._reg("priority", Bits(len(din_vlds)), def_val=1)
            priority(rol(priority, 1))

            isSelectedFlags = []
            for i, din_vld in enumerate(din_vlds):
                isSelected = self._sig(f"isSelected_{i:d}")
                isSelected(self.priorityAck(priority, din_vlds, i))
                isSelectedFlags.append(isSelected)

                if selectedOneHot is not None:
                    selectedOneHot.data[i](isSelected & din_vld)

        if selectedOneHot is not None:
            selectedOneHot.vld(Or(*din_vlds) & dout_rd)

        return isSelectedFlags
Пример #11
0
    def test_syncSigWithReset(self):
        c = self.n
        clk = c.sig("ap_clk")
        rst = c.sig("ap_rst")
        a = c.sig("a", clk=clk, syncRst=rst, def_val=0)

        self.assertEqual(len(a.drivers), 1)

        _if = a.drivers[0]
        self.assertIsInstance(_if, If)

        self.assertIs(_if.cond, clk._onRisingEdge())
        self.assertEqual(len(_if.ifTrue), 1)
        self.assertEqual(_if.ifFalse, None)
        self.assertEqual(len(_if.elIfs), 0)

        if_reset = _if.ifTrue[0]

        self.assertIs(if_reset.cond, rst._isOn())
        self.assertEqual(len(if_reset.ifTrue), 1)
        self.assertEqual(len(if_reset.ifFalse), 1)
        self.assertEqual(len(if_reset.elIfs), 0)

        a_reset = if_reset.ifTrue[0]
        a_next = if_reset.ifFalse[0]
        self.assertIsInstance(a_reset, Assignment)
        self.assertEqual(a_reset.src, BIT.from_py(0))

        self.assertIsInstance(a_next, Assignment)
        self.assertEqual(a_next.src, a.next)
Пример #12
0
    def _impl(self) -> None:
        if len(self.MASTERS) > 1:
            raise NotImplementedError()

        m = self.s[0]

        wrack = rdack = err = BIT.from_py(0)
        AW = int(self.ADDR_WIDTH)
        rdata = []
        for i, (s, (s_offset, s_size)) in\
                enumerate(zip(self.m, self.SLAVES)):
            s.bus2ip_addr(m.bus2ip_addr, fit=True)
            s.bus2ip_be(m.bus2ip_be)
            s.bus2ip_rnw(m.bus2ip_rnw)
            s.bus2ip_data(m.bus2ip_data)

            bitsOfSubAddr = log2ceil(s_size - 1)
            prefix = get_bit_range(s_offset, bitsOfSubAddr, AW - bitsOfSubAddr)
            cs = self._sig(f"m_cs_{i:d}")
            cs(m.bus2ip_addr[AW:bitsOfSubAddr]._eq(prefix))
            s.bus2ip_cs(m.bus2ip_cs & cs)

            err = err | (cs & s.ip2bus_error)
            rdack = rdack | (cs & s.ip2bus_rdack)
            wrack = wrack | (cs & s.ip2bus_wrack)
            rdata.append((cs, s.ip2bus_data))

        m.ip2bus_error(err)
        m.ip2bus_rdack(rdack)
        m.ip2bus_wrack(wrack)

        SwitchLogic([(sel, m.ip2bus_data(data)) for sel, data in rdata],
                    default=m.ip2bus_data(None))
Пример #13
0
 def type_check_bit_param(self, name):
     v = getattr(self, name)
     if not isinstance(v, BIT.getValueCls()):
         v = BIT.from_py(v)
         object.__setattr__(self, name, v)
     else:
         assert v._dtype == BIT, (name, "must be of type ", BIT,
                                  " or compatible, is:", v)
Пример #14
0
    def ack(self) -> RtlSignal:
        ack = BIT.from_py(1)
        if self:
            acks = [
                x[1].ack() & self.selectorIntf.data._eq(x[0]) for x in self
            ]
            ack = Or(*acks)

        return ack & self.selectorIntf.vld
Пример #15
0
    def is_footer_mask_set_values(self, LOOK_AHEAD, regs):
        D_W = self.DATA_WIDTH
        BYTE_CNT = D_W // 8
        FOOTER_WIDTH = self.FOOTER_WIDTH
        din = self.dataIn

        if self.USE_KEEP:
            in_mask = din.keep
        elif self.USE_STRB:
            in_mask = din.strb
        elif self.DATA_WIDTH == 8:
            in_mask = BIT.from_py(1, 1)
        else:
            raise NotImplementedError(
                "keep/strb can be ignored only for DATA_WIDTH=8")

        set_is_footer = self._sig("set_is_footer")
        set_is_footer(din.valid & din.last)
        mask_cases = []
        for last_B_valid, bytes_in_last_input_word in iter_with_last(
                range(1, BYTE_CNT + 1)):
            footer_end = (LOOK_AHEAD * BYTE_CNT + bytes_in_last_input_word) * 8
            footer_start = footer_end - FOOTER_WIDTH
            assert footer_start > 0, (
                "otherwise we would not be able to send last for previous frame",
                footer_start)
            assert footer_start < D_W * 3, (
                "footer start can appear only in last-1 or last-2 regster,"
                " last register is output register", footer_start, D_W)
            _is_footer = set_bit_range(0, footer_start // 8, FOOTER_WIDTH // 8,
                                       mask(FOOTER_WIDTH // 8))
            set_flags = []
            for i, (_, _, is_footer_set_val, _, _) in enumerate(regs):
                if i == 0:
                    is_footer_val = 0
                    is_footer_val_last_word = get_bit_range(
                        _is_footer, (LOOK_AHEAD - i) * BYTE_CNT, BYTE_CNT)
                    set_flags.append(
                        If(set_is_footer,
                           is_footer_set_val(is_footer_val_last_word)).Else(
                               is_footer_set_val(is_footer_val)))
                else:
                    is_footer_val = get_bit_range(
                        _is_footer, (LOOK_AHEAD - i + 1) * BYTE_CNT, BYTE_CNT)
                    set_flags.append(is_footer_set_val(is_footer_val))

            if last_B_valid:
                # last byte also valid
                mask_default = set_flags
            else:
                # last 0 from the end of the validity mask
                mask_cases.append(
                    (~in_mask[bytes_in_last_input_word], set_flags))

        SwitchLogic(mask_cases, mask_default)
        return set_is_footer
Пример #16
0
    def Operator(cls, op: Operator, ctx):
        ops = op.operands
        o = op.operator

        op_str = cls._unaryOps.get(o, None)
        if op_str is not None:
            cancel_parenthesis = op_str.endswith(")")
            return op_str % (cls._operand(ops[0], 0, op, False, cancel_parenthesis, ctx))

        op_str = cls._binOps.get(o, None)
        if op_str is not None:
            return cls._bin_op(op, op_str, ctx, cancel_parenthesis=o == AllOps.CONCAT)
        if o == AllOps.CALL:
            return "%s(%s)" % (
                cls.FunctionContainer(ops[0]),
                # operand i does not matter as they are all in ()
                ", ".join(map(lambda _op: cls._operand(_op, 1, op, False, True, ctx), ops[1:])))
        elif o == AllOps.INDEX:
            return cls._operator_index(op, ctx)
        elif o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return cls.condAsHdl([ops[0]], True, ctx)
            else:
                op0 = cls.condAsHdl([ops[0]], True, ctx)
                op1 = cls._operand(ops[1], op, False, False, ctx)
                op2 = cls._operand(ops[2], op, False, False, ctx)
                return "%s ? %s : %s" % (op0, op1, op2)
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            raise UnsupportedEventOpErr()
        elif o in [AllOps.BitsAsUnsigned, AllOps.BitsAsVec]:
            op0, = ops
            do_cast = bool(op0._dtype.signed)
            op_str = cls._operand(op0, op, False, do_cast, ctx)
            if do_cast:
                return "$unsigned(%s)" % op_str
            else:
                return op_str
        else:
            raise NotImplementedError(
                "Do not know how to convert expression with operator %s to verilog" % (o))
Пример #17
0
    def ack(self) -> RtlSignal:
        if self.wordIndexReg is None:
            getAck = self._getAck_no_wordIndex
        else:
            getAck = self._getAck_with_wordIndex

        acks = [getAck(w) for w in self.words]

        if acks:
            return Or(*acks)
        else:
            return BIT.from_py(1)
Пример #18
0
 def is_in_word_range(self, range_min: int, range_max: int):
     if range_min > range_max:
         return False
     w = self.streamGroup.word_index
     if w is None:
         return BIT.from_py(1)
     if range_min == range_max:
         en = w._eq(range_min)
     elif range_min == 0:
         en = (w <= (range_max))
     else:
         en = ((w > (range_min - 1)) & (w <= (range_max)))
     return en
Пример #19
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()
Пример #20
0
    def parser_fsm(self, words):
        din = self.dataIn
        maxWordIndex = words[-1][0]

        word_index_max_val = maxWordIndex
        if self.OVERFLOW_SUPPORT:
            word_index_max_val += 1
        hasMultipleWords = word_index_max_val > 0
        if hasMultipleWords:
            wordIndex = self._reg("wordIndex", Bits(
                log2ceil(word_index_max_val + 1)), 0)
        else:
            wordIndex = None

        allOutNodes = WordFactory(wordIndex)
        if not is_only_padding(self._structT):
            fc = AxiS_frameParserFieldConnector(self, self.dataIn, self.dataOut)
            fc.connectParts(allOutNodes, words, wordIndex)

        in_vld = din.valid
        if self.SHARED_READY:
            out_ready = self.dataOut_ready
            din.ready(out_ready)
        else:
            out_ready = self._sig("out_ready")
            out_ready(allOutNodes.ack())
            allOutNodes.sync(BIT.from_py(1), in_vld)

        din.ready(out_ready)

        if hasMultipleWords:
            last = wordIndex._eq(maxWordIndex)
            incr = wordIndex(wordIndex + 1)
            if self.OVERFLOW_SUPPORT:
                incr = If(wordIndex != word_index_max_val,
                   incr
                )
                aligned = self._structT.bit_length() % self.DATA_WIDTH == 0
                if aligned:
                    overflow = wordIndex._eq(word_index_max_val)
                else:
                    overflow = wordIndex >= maxWordIndex
                self.parsing_overflow(overflow)

            If(in_vld & out_ready,
                If(last,
                   wordIndex(0)
                ).Else(
                   incr
                )
            )
Пример #21
0
    def generate_regs(
        self, LOOK_AHEAD
    ) -> List[Tuple[RtlSignal, RtlSignal, RtlSignal, RtlSignal, RtlSignal]]:
        din = self.dataIn
        mask_t = Bits(self.DATA_WIDTH // 8, force_vector=True)
        data_fieds = [
            (din.data._dtype, "data"),
            # flag for end of input frame
            (BIT, "last"),
            (BIT, "valid"),
        ]
        if self.USE_KEEP:
            data_fieds.append((mask_t, "keep"))
        if self.USE_STRB:
            data_fieds.append((mask_t, "strb"))

        reg_t = HStruct(*data_fieds)
        regs = []
        # 0 is dataIn, 1 is connected to dataIn, ..., n connected to dataOut
        for last, i in iter_with_last(range(LOOK_AHEAD + 1 + 1)):
            if i == 0:
                r = din
                ready = din.ready
                can_flush = BIT.from_py(0)
                is_footer = self._sig("dataIn_is_footer", mask_t)
                is_footer_set_val = is_footer  # because it is always set
            elif last:
                r = self._reg("out_reg", reg_t, def_val={"valid": 0})
                ready = self._sig("out_reg_ready")
                can_flush = self._sig("out_reg_can_flush")
                is_footer = self._reg("out_reg_is_footer", mask_t, def_val=0)
                is_footer_set_val = self._sig("out_reg_is_footer_set_val",
                                              mask_t)
            else:
                r = self._reg(f"r{i:d}", reg_t, def_val={"valid": 0})
                ready = self._sig(f"r{i:d}_ready")
                can_flush = self._sig(f"r{i:d}_can_flush")
                is_footer = self._reg(f"r{i:d}_is_footer", mask_t, def_val=0)
                is_footer_set_val = self._sig(f"r{i:d}_is_footer_set_val",
                                              mask_t)
            # :var ready: signal which is 1 if this register can accept data
            # :var can_flush: tells if this register can pass it's value to next
            #     even if prev does not contain valid data
            #     and the hole in data may be created
            # :var is_footer: mask with 1 for footer bytes
            # :var is_footer_set_val: value of is_footer which will be set if end
            #     of frame is detected
            regs.append((r, is_footer, is_footer_set_val, can_flush, ready))

        return regs
Пример #22
0
 def _impl(self):
     a = self.a
     b = self.b
     self.c(
         Concat(
             BIT.from_py(1),
             Bits(3).from_py(7),
             a != b,
             a < b,
             a <= b,
             a._eq(b),
             a >= b,
             a > b,
             Bits(22).from_py(0),
         ))
Пример #23
0
    def count_leading(cls, data_in: RtlSignal, data_out: RtlSignal,
                      bit_to_count: int):
        in_width = data_in._dtype.bit_length()
        assert bit_to_count in (0, 1), bit_to_count

        if bit_to_count == 0:
            full = data_in._eq(0)
        else:
            full = data_in._eq(mask(in_width))

        half_count = cls._count_leading_recurse(data_in, bit_to_count)
        If(
            full,
            data_out(in_width),
        ).Else(data_out(Concat(BIT.from_py(0), half_count)))
Пример #24
0
    def ackForMaster(self, master):
        """
        :return: driver of ready signal for master
        """
        otherMasters = where(self.masters, lambda x: x is not master)
        extra, skip = self.getExtraAndSkip(master)

        conds = [*map(self.vld, otherMasters),
                 *map(self.rd, self.slaves),
                 *extra]
        if conds:
            r = And(*conds)
        else:
            r = BIT.from_py(1)

        if skip is not None:
            r = r & ~skip

        return r
Пример #25
0
    def ackForSlave(self, slave):
        """
        :return: driver of valid signal for slave
        """
        otherSlaves = where(self.slaves, lambda x: x is not slave)
        extra, skip = self.getExtraAndSkip(slave)

        conds = [*map(self.vld, self.masters),
                 *map(self.rd, otherSlaves),
                 *extra]
        if conds:
            v = And(*conds)
        else:
            v = BIT.from_py(1)

        if skip is not None:
            v = v & ~skip

        return v
Пример #26
0
    def applyCrcXorMatrix(cls, crcMatrix: List[List[List[int]]],
                          inBits: List[RtlSignal],
                          stateBits: List[Union[RtlSignal, BitsVal]],
                          refin: bool) -> List:
        if refin:
            inBits = bit_list_reversed_bits_in_bytes(inBits, extend=False)
        outBits = []
        for (stateMask, dataMask) in crcMatrix:
            v = BIT.from_py(0)  # neutral value for XOR
            assert len(stateMask) == len(stateBits)
            for useBit, b in zip(stateMask, stateBits):
                if useBit:
                    v = v ^ b

            assert len(dataMask) == len(inBits), (len(dataMask), len(inBits))
            for useBit, b in zip(dataMask, inBits):
                if useBit:
                    v = v ^ b

            outBits.append(v)

        assert len(outBits) == len(stateBits)
        return outBits
Пример #27
0
    def Operator(cls, op, ctx):
        ops = op.operands
        o = op.operator

        op_str = cls._unaryOps.get(o, None)
        if op_str is not None:
            return op_str % (cls._operand(ops[0], 0, op, False, False, ctx))

        op_str = cls._binOps.get(o, None)
        if op_str is not None:
            return op_str % (cls._operand(ops[0], 0, op, False, False, ctx),
                             cls._operand(ops[1], 1, op, False, False, ctx))

        if o == AllOps.INDEX:
            assert len(ops) == 2
            o0, o1 = ops
            o0_str = cls._operand(o0, 0, op, True, False, ctx)
            if ops[1]._dtype == SLICE:
                return "%s.range(%s, %s)" % (
                    o0_str,
                    # not operator i does not matter as they are all in ()
                    cls._operand(o1.val.start, 1, op, False, True, ctx),
                    cls._operand(o1.val.stop, 1, op, False, True, ctx))
            else:
                return "%s[%s]" % (o0_str,
                                   cls._operand(o1, 1, op, False, True, ctx))

        elif o == AllOps.TERNARY:
            zero, one = BIT.from_py(0), BIT.from_py(1)
            if ops[1] == one and ops[2] == zero:
                # ignore redundant x ? 1 : 0
                return cls.condAsHdl([ops[0]], True, ctx)
            else:
                return "%s ? %s : %s" % (
                    cls.condAsHdl([ops[0]], True, ctx),
                    cls._operand(ops[1], 1, op, False, False, ctx),
                    cls._operand(ops[2], 2, op, False, False, ctx))
        elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE:
            if ctx.isSensitivityList:
                if o == AllOps.RISING_EDGE:
                    _o = ".pos()"
                else:
                    _o = ".neg()"
                return cls._operand(ops[0], 0, op, True, False, ctx) + _o
            else:
                raise UnsupportedEventOpErr()
        elif o in [
                AllOps.BitsAsSigned, AllOps.BitsAsUnsigned, AllOps.BitsAsVec
        ]:
            assert len(ops) == 1
            return "static_cast<%s>(%s)" % (cls.HdlType(
                op.result._dtype,
                ctx), cls._operand(ops[0], 0, op, False, True, ctx))
        elif o == AllOps.POW:
            assert len(ops) == 2
            raise NotImplementedError()
            # return _bin('**')
        elif o == AllOps.CALL:
            return "%s(%s)" % (cls.FunctionContainer(ops[0]), ", ".join(
                map(lambda op: cls._operand(op, 1, op, False, True, ctx),
                    ops[1:])))
        else:
            raise NotImplementedError("Do not know how to convert %s to vhdl" %
                                      (o))
Пример #28
0
from hdlConvertorAst.translate.common.name_scope import LanguageKeyword
from hwt.code import Concat
from hwt.hdl.operator import Operator
from hwt.hdl.operatorDefs import AllOps
from hwt.hdl.types.bitsVal import BitsVal
from hwt.hdl.types.defs import BIT
from hwt.hdl.types.enum import HEnum
from hwt.hdl.types.enumVal import HEnumVal
from hwt.hdl.value import HValue
from hwt.hdl.variables import SignalItem
from hwt.serializer.generic.ops import HWT_TO_HDLCONVEROTR_OPS
from hwt.serializer.generic.value import ToHdlAst_Value
from pyMathBitPrecise.array3t import Array3val
from pyMathBitPrecise.bits3t import Bits3val, Bits3t

zero, one = BIT.from_py(0), BIT.from_py(1)


class ToHdlAstSimModel_value(ToHdlAst_Value):
    Bits3val = HdlValueId("Bits3val", obj=Bits3val)
    Bits3t = HdlValueId("Bits3t", obj=Bits3t)
    SELF = HdlValueId("self", obj=LanguageKeyword())
    Array3val = HdlValueId("Array3val", obj=Array3val)
    SLICE = HdlValueId("slice", obj=slice)
    TRUE = HdlValueId("True", obj=True)
    FALSE = HdlValueId("False", obj=False)
    Bits3val = HdlValueId("Bits3val", obj=Bits3val)
    ABits3t = HdlValueId("Bits3t", obj=Bits3t)
    SELF_IO = hdl_getattr(HdlValueId("self", obj=LanguageKeyword()), "io")
    CONCAT = HdlValueId("Concat", obj=Concat)
    op_transl_dict = {
Пример #29
0
Файл: w.py Проект: mfkiwl/hwtLib
    def axiWHandler(self, wErrFlag: RtlSignal):
        w = self.axi.w
        wIn = self.driver.w
        wInfo = self.writeInfoFifo.dataOut
        bInfo = self.bInfoFifo.dataIn

        dataAck = self._sig("dataAck")
        inLast = wIn.last
        if hasattr(w, "id"):
            # AXI3 has id signal, AXI4 does not
            w.id(self.ID_VAL)

        if self.isAlwaysAligned():
            w.data(wIn.data)
            w.strb(wIn.strb)
            if self.axi.LEN_WIDTH:
                doSplit = wIn.last
            else:
                doSplit = BIT.from_py(1)

            waitForShift = BIT.from_py(0)
        else:
            isFirst = self._reg("isFirstData", def_val=1)
            prevData = self._reg("prevData",
                                 HStruct(
                                     (wIn.data._dtype, "data"),
                                     (wIn.strb._dtype, "strb"),
                                     (BIT, "waitingForShift"),
                                 ),
                                 def_val={"waitingForShift": 0})

            waitForShift = prevData.waitingForShift
            isShifted = (wInfo.shift != 0) | (wInfo.SHIFT_OPTIONS[0] != 0)
            wInWillWaitForShift = wIn.valid & wIn.last & isShifted & ~prevData.waitingForShift & ~wInfo.drop_last_word

            If(
                StreamNode([wIn, wInfo], [w, bInfo],
                           skipWhen={
                               wIn: waitForShift
                           }).ack() & ~wErrFlag,
                # data feed in to prevData is stalled if we need to dispath
                # the remainder from previous word which was not yet dispatched due data shift
                # the last data from wIn is consumed on wIn.last, however there is 1 beat stall
                # for wIn i transaction was not aligned. wInfo and bInfo channels are activated
                # after last beat of wOut is send
                If(
                    ~prevData.waitingForShift,
                    prevData.data(wIn.data),
                    prevData.strb(wIn.strb),
                ),
                waitForShift(wInWillWaitForShift),
                isFirst((isShifted & waitForShift)
                        | ((~isShifted | wInfo.drop_last_word) & wIn.last)))

            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])), )
                    ]

            Switch(wInfo.shift).add_cases([
                (i, applyShift(sh)) for i, sh in enumerate(wInfo.SHIFT_OPTIONS)
            ]).Default(
                w.data(None),
                w.strb(None),
            )
            inLast = rename_signal(
                self,
                isShifted._ternary(
                    waitForShift | (wIn.last & wInfo.drop_last_word),
                    wIn.last), "inLast")
            doSplit = inLast

        if self.useTransSplitting():
            wordCntr = self._reg("wWordCntr", self.getLen_t(), 0)
            doSplit = rename_signal(
                self,
                wordCntr._eq(self.getAxiLenMax()) | doSplit, "doSplit1")

            If(
                StreamNode([wInfo, wIn], [bInfo, w]).ack() & ~wErrFlag,
                If(doSplit, wordCntr(0)).Else(wordCntr(wordCntr + 1)))
        if self.AXI_CLS.LEN_WIDTH != 0:
            w.last(doSplit)

        # if this frame was split into a multiple frames wIn.last will equal 0
        bInfo.isLast(inLast)
        dataNode = StreamNode(masters=[wIn, wInfo],
                              slaves=[bInfo, w],
                              skipWhen={
                                  wIn: waitForShift,
                              },
                              extraConds={
                                  wIn: ~waitForShift,
                                  wInfo: doSplit,
                                  bInfo: doSplit,
                                  w: ~wErrFlag
                              })
        dataAck(dataNode.ack())
        dataNode.sync()
Пример #30
0
    u.CLKFBOUT_PHASE = 0.0
    u.CLKFBOUT_USE_FINE_PS = False
    u.CLKIN1_PERIOD = 10.0
    u.CLKIN2_PERIOD = 0.0
    u.CLKOUT0_DIVIDE_F = 10.0
    u.CLKOUT0_DUTY_CYCLE = 0.5
    u.CLKOUT0_PHASE = 0.0
    u.CLKOUT0_USE_FINE_PS = False
    for i in range(1, 6 + 1):
        setattr(u, f"CLKOUT{i:d}_DIVIDE", 1)
        setattr(u, f"CLKOUT{i:d}_DUTY_CYCLE", 0.5)
        setattr(u, f"CLKOUT{i:d}_PHASE", 0.0)
        setattr(u, f"CLKOUT{i:d}_USE_FINE_PS", False)
    u.CLKOUT4_CASCADE = False

    u.COMPENSATION = "ZHOLD"
    u.DIVCLK_DIVIDE = 1
    u.IS_CLKINSEL_INVERTED = BIT.from_py(0)
    u.IS_PSEN_INVERTED = BIT.from_py(0)
    u.IS_PSINCDEC_INVERTED = BIT.from_py(0)
    u.IS_PWRDWN_INVERTED = BIT.from_py(0)
    u.IS_RST_INVERTED = BIT.from_py(0)
    u.REF_JITTER1 = 0.01
    u.REF_JITTER2 = 0.01
    u.SS_EN = "FALSE"
    u.SS_MODE = "CENTER_HIGH"
    u.SS_MOD_PERIOD = 10000
    u.STARTUP_WAIT = "FALSE"

    print(to_rtl_str(u, target_platform=XilinxVivadoPlatform()))