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)])
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)
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)
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")
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])
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)
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)
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})")
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)
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
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)
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))
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)
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
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
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))
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)
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
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()
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 ) )
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
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), ))
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)))
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
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
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
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))
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 = {
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()
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()))