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 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 _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 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], o, ctx)) op_str = cls._binOps.get(o, None) if op_str is not None: return op_str % (cls._operand(ops[0], o, ctx), cls._operand(ops[1], o, ctx)) if o == AllOps.INDEX: assert len(ops) == 2 o0, o1 = ops o0_str = cls.asHdl(o0, ctx) if ops[1]._dtype == SLICE: return "%s.range(%s, %s)" % (o0_str, cls._operand(o1.val[0], o, ctx), cls._operand(o1.val[1], o, ctx)) else: return "%s[%s]" % (o0_str, cls._operand(o1, o, ctx)) elif o == AllOps.TERNARY: zero, one = BIT.fromPy(0), BIT.fromPy(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], o, ctx), cls._operand(ops[2], o, 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], o, ctx) + _o else: raise UnsupportedEventOpErr() elif o in [ AllOps.BitsAsSigned, AllOps.BitsAsUnsigned, AllOps.BitsAsVec, AllOps.IntToBits ]: assert len(ops) == 1 return "static_cast<%s>(%s)" % (cls.HdlType( op.result._dtype, ctx), cls._operand(ops[0], o, 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, o, ctx), ops[1:]))) else: raise NotImplementedError("Do not know how to convert %s to vhdl" % (o))
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 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 __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 _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 cast_hbool(self, sigOrVal, toType): if toType == BIT: if isinstance(sigOrVal, Value): v = BIT.getValueCls()(int(sigOrVal.val), BIT, sigOrVal.vldMask, sigOrVal.updateTime) return v else: return sigOrVal._ternary(BIT.fromPy(1), BIT.fromPy(0)) return default_auto_cast_fn(self, sigOrVal, toType)
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 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 type_check_bool_param(self, name): STR_BOOL = ("TRUE", "FALSE") v = getattr(self, name) if self._store_manager.serializer_cls == VerilogSerializer: # for verilog we need to convert it to "TRUE" or "FALSE" string if not isinstance(v, STR.getValueCls()): if isinstance(v, (bool, BIT.getValueCls())): v = "TRUE" if v else "FALSE" else: assert v in STR_BOOL, (name, v) v = STR.from_py(v) object.__setattr__(self, name, v) else: assert v._dtype == STR, (name, "must be of type ", STR, " or compatible, is:", v) else: if not isinstance(v, BOOL.getValueCls()): if isinstance(v, (str, STR.getValueCls())): v = str(v) if v == "FALSE": v = False elif v == "TRUE": v = True else: raise AssertionError( name, "must be of type ", BOOL, " or string \"TRUE\" or \"FALSE\" or compatible, is:", v) v = BOOL.from_py(v) object.__setattr__(self, name, v) else: assert v._dtype == BOOL, (name, "must be of type ", BOOL, " or compatible, is:", v)
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 _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 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 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], o, ctx)) op_str = cls._binOps.get(o, None) if op_str is not None: return op_str % (cls._operand(ops[0], o, ctx), cls._operand(ops[1], o, ctx)) if o == AllOps.CALL: return "%s(%s)" % (cls.FunctionContainer(ops[0]), ", ".join( map(lambda op: cls._operand(op, o, ctx), ops[1:]))) elif o == AllOps.INDEX: assert len(ops) == 2 o1 = ops[0] return "%s[%s]" % (cls.asHdl( o1, ctx).strip(), cls._operand(ops[1], o, ctx)) elif o == AllOps.TERNARY: zero, one = BIT.fromPy(0), BIT.fromPy(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], o, ctx), cls._operand(ops[2], o, ctx)) elif o == AllOps.RISING_EDGE or o == AllOps.FALLING_EDGE: raise UnsupportedEventOpErr() elif o in [AllOps.BitsAsUnsigned, AllOps.BitsAsVec]: op, = ops op_str = cls._operand(op, o, ctx) if bool(op._dtype.signed): return "$unsigned(%s)" % op_str else: return op_str else: raise NotImplementedError("Do not know how to convert %s to vhdl" % (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