def select_data_word_from_ouput_word(self, m, s): w_align_fifo = self.propagate_addr(m.aw, s.aw) r_align_fifo = self.propagate_addr(m.ar, s.ar) AL_IN_W = self.ALIGN_BITS_IN AL_OUT_W = self.ALIGN_BITS_OUT ALIG_W = AL_OUT_W - AL_IN_W assert ALIG_W > 0, ALIG_W r_align_cases = [] w_align_cases = [] for i in range(2**ALIG_W): r_align_cases.append((i, self.connect_shifted(s.r, m.r, i))) w_align_cases.append((i, self.connect_shifted(m.w, s.w, i))) s.w(m.w, exclude={m.w.data, m.w.strb, m.w.ready, m.w.valid}) StreamNode(masters=[m.w, w_align_fifo.dataOut], slaves=[s.w]).sync() Switch(w_align_fifo.dataOut.data).add_cases(w_align_cases)\ .Default( # case which was unexpected or was filtered out by IN_ADDR_GRANULARITY s.w.data(None), s.w.strb(None), ) m.r(s.r, exclude={s.r.data, s.r.ready, s.r.valid}) StreamNode(masters=[s.r, r_align_fifo.dataOut], slaves=[m.r]).sync() Switch(r_align_fifo.dataOut.data).add_cases(r_align_cases)\ .Default( # case which was unexpected or was filtered out by IN_ADDR_GRANULARITY m.r.data(None), ) m.b(s.b)
def test_SwitchContainer_try_reduce__empty(self): nl = RtlNetlist() a = nl.sig("a", BIT) s0 = Switch(a).add_cases([(hBit(0), []), (hBit(1), [])]) s0_red, io_change = s0._try_reduce() self.assertFalse(io_change) self.assertEqual(s0_red, [])
def _impl(self): self._parseTemplate() bus = self.bus def connectRegIntfAlways(regIntf, _addr): return ( c(bus.din, regIntf.dout.data) + c(bus.we & bus.en & bus.addr._eq(_addr), regIntf.dout.vld) ) ADDR_STEP = self._getAddrStep() if self._directlyMapped: readReg = self._reg("readReg", dtype=bus.dout._dtype) # tuples (condition, assign statements) readRegInputs = [] for t in self._directlyMapped: port = self.getPort(t) _addr = t.bitAddr // ADDR_STEP connectRegIntfAlways(port, _addr) readRegInputs.append((bus.addr._eq(_addr), readReg(port.din) )) SwitchLogic(readRegInputs) else: readReg = None if self._bramPortMapped: BRAMS_CNT = len(self._bramPortMapped) bramIndxCases = [] readBramIndx = self._reg("readBramIndx", Bits( log2ceil(BRAMS_CNT + 1), False)) outputSwitch = Switch(readBramIndx) for i, t in enumerate(self._bramPortMapped): # if we can use prefix instead of addr comparing do it _addr = t.bitAddr // ADDR_STEP _addrEnd = t.bitAddrEnd // ADDR_STEP port = self.getPort(t) _addrVld, _ = self.propagateAddr(bus.addr, ADDR_STEP, port.addr, port.dout._dtype.bit_length(), t) port.we(bus.we & _addrVld & bus.en) port.en(bus.en & _addrVld & bus.en) port.din(bus.din) bramIndxCases.append((_addrVld, readBramIndx(i))) outputSwitch.Case(i, bus.dout(port.dout)) outputSwitch.Default(bus.dout(readReg)) SwitchLogic(bramIndxCases, default=readBramIndx(BRAMS_CNT)) else: bus.dout(readReg)
def generate_output_byte_mux(self, regs): out_mux_values = [set() for _ in range(self.word_bytes)] for st in self.state_trans_table.state_trans: for stt in st: for o_mux_val, out_mux_val_set in zip(stt.out_byte_mux_sel, out_mux_values): if o_mux_val is not None: out_mux_val_set.add(o_mux_val) out_mux_values = [sorted(x) for x in out_mux_values] def index_byte(sig, byte_i): return sig[(byte_i+1)*8:byte_i*8] def get_in_byte(input_i, time_offset, byte_i): return index_byte(regs[input_i][time_offset].data, byte_i) def data_drive(out_B, out_strb_b, input_i, time_offset, byte_i): res = [ out_B(get_in_byte(input_i, time_offset, byte_i)) ] if self.USE_STRB: res.append( out_strb_b(regs[input_i][time_offset].strb[byte_i]) ) return res out_byte_sel = [] for out_B_i, out_byte_mux_vals in enumerate(out_mux_values): # +1 because last value is used to invalidate data sel_w = log2ceil(len(out_byte_mux_vals) + 1) sel = self._sig(f"out_byte{out_B_i:d}_sel", Bits(sel_w)) out_byte_sel.append(sel) out_B = self._sig(f"out_byte{out_B_i:d}", Bits(8)) index_byte(self.dataOut.data, out_B_i)(out_B) if self.USE_STRB: out_strb_b = self._sig(f"out_strb{out_B_i:d}") self.dataOut.strb[out_B_i](out_strb_b) else: out_strb_b = None sw = Switch(sel).add_cases( (i, data_drive(out_B, out_strb_b, *val)) for i, val in enumerate(out_byte_mux_vals)) # :note: default case is threre for the case of faulire where # sel has non predicted value default_case = [out_B(None)] if self.USE_STRB: default_case.append(out_strb_b(0)) sw.Default(*default_case) return out_byte_sel, out_mux_values
def test_basicSwitch(self): a = self.n.sig('a', dtype=INT) b = self.n.sig('b', dtype=INT) obj = Switch(a).addCases([(i, c(i, b)) for i in range(4)]) cont, io_change = obj._try_reduce() self.assertFalse(io_change) self.assertEqual(len(cont), 1) cont = cont[0] tmpl = SwitchContainer(a, [(i, c(i, b)) for i in range(3)] + [(None, c(3, b))]) self.compareStructure(tmpl, cont)
def test_SwitchContainer_try_reduce__all(self): nl = RtlNetlist() a = nl.sig("a", BIT) b = nl.sig("b", BIT) s0 = Switch(a).add_cases([(hBit(0), [ b(0), ]), (hBit(1), [ b(0), ])]) s0_red, io_change = s0._try_reduce() self.assertFalse(io_change) self.assertEqual(len(s0_red), 1) self.assertTrue(s0_red[0].isSame(b(0)))
def _impl(self): # :note: stT member names are colliding with port names and thus # they will be renamed in HDL stT = HEnum("st_t", ["a", "b", "aAndB"]) a = self.a b = self.b out = self.dout st = FsmBuilder(self, stT)\ .Trans(stT.a, (a & b, stT.aAndB), (b, stT.b) ).Trans(stT.b, (a & b, stT.aAndB), (a, stT.a) ).Trans(stT.aAndB, (a & ~b, stT.a), (~a & b, stT.b), ).stateReg Switch(st)\ .Case(stT.a, out(1) ).Case(stT.b, out(2) ).Case(stT.aAndB, out(3) )
def mainFsm(self, st, onoff, lenRem, actualLenRem): axi = self.axi st_t = st._dtype w_ackAll = self.w_allAck(st) Switch(st)\ .Case(st_t.fullIdle, If(onoff, st(st_t.writeAddr) ) ).Case(st_t.writeAddr, If(axi.aw.ready, If(lenRem._eq(1), st(st_t.writeDataLast) ).Else( st(st_t.writeData) ) ) ).Case(st_t.writeData, If(w_ackAll & (actualLenRem._eq(2)), st(st_t.writeDataLast) ) ).Case(st_t.writeDataLast, If(w_ackAll, If(lenRem != 0, st(st_t.writeAddr) ).Else( st(st_t.fullIdle) ) ) )
def wHandler(self): w = self.wDatapump.w fWOut = self.orderInfoFifoW.dataOut fAckIn = self.orderInfoFifoAck.dataIn driversW = list(map(lambda d: d.w, self.drivers)) selectedDriverVld = self._sig("selectedDriverWVld") selectedDriverVld(Or(*map(lambda d: fWOut.data._eq(d[0]) & d[1].valid, enumerate(driversW)) )) selectedDriverLast = self._sig("selectedDriverLast") selectedDriverLast(Or(*map(lambda d: fWOut.data._eq(d[0]) & d[1].last, enumerate(driversW)) )) Switch(fWOut.data).addCases( [(i, connect(d, w, exclude=[d.valid, d.ready])) for i, d in enumerate(driversW)] ).Default( w.data(None), w.strb(None), w.last(None) ) fAckIn.data(fWOut.data) # handshake logic fWOut.rd(selectedDriverVld & selectedDriverLast & w.ready & fAckIn.rd) for i, d in enumerate(driversW): d.ready(fWOut.data._eq(i) & w.ready & fWOut.vld & fAckIn.rd) w.valid(selectedDriverVld & fWOut.vld & fAckIn.rd) fAckIn.vld(selectedDriverVld & selectedDriverLast & w.ready & fWOut.vld)
def _downscale(self, factor): inputRegs_cntr = self._reg("inputRegs_cntr", Bits(log2ceil(factor + 1), False), def_val=0) # instantiate HandshakedReg, handshaked builder is not used to avoid dependencies inReg = HandshakedReg(self.intfCls) inReg._updateParamsFrom(self.dataIn) self.inReg = inReg inReg.clk(self.clk) inReg.rst_n(self.rst_n) inReg.dataIn(self.dataIn) dataIn = inReg.dataOut dataOut = self.dataOut # create output mux for din, dout in zip(self.get_data(dataIn), self.get_data(dataOut)): widthOfPart = din._dtype.bit_length() // factor inParts = iterBits(din, bitsInOne=widthOfPart) Switch(inputRegs_cntr).add_cases( [(i, dout(inPart)) for i, inPart in enumerate(inParts)] ) vld = self.get_valid_signal rd = self.get_ready_signal vld(dataOut)(vld(dataIn)) self.get_ready_signal(dataIn)(inputRegs_cntr._eq(factor - 1) & rd(dataOut)) If(vld(dataIn) & rd(dataOut), If(inputRegs_cntr._eq(factor - 1), inputRegs_cntr(0) ).Else( inputRegs_cntr(inputRegs_cntr + 1) ) )
def _impl(self): a = self.a b = self.b out = self.dout st = self._reg("st", Bits(3), 1) If(st._eq(1), If(a & b, st(3)).Elif(b, st(2))).Elif(st._eq(2), If(a & b, st(3)).Elif(a, st(1))).Elif( st._eq(3), If(a & ~b, st(1)).Elif(~a & b, st(2))).Else(st(1)) Switch(st)\ .Case(1, out(1) ).Case(2, out(2) ).Case(3, out(3) ).Default( out(None) )
def _impl(self): stT = HEnum("st_t", ["a", "b", "aAndB"]) a = self.a b = self.b out = self.dout st = FsmBuilder(self, stT)\ .Trans(stT.a, (a & b, stT.aAndB), (b, stT.b) ).Trans(stT.b, (a & b, stT.aAndB), (a, stT.a) ).Trans(stT.aAndB, (a & ~b, stT.a), (~a & b, stT.b), ).stateReg Switch(st)\ .Case(stT.a, out(1) ).Case(stT.b, out(2) ).Case(stT.aAndB, out(3) )
def _impl(self): dec = [ # 0 0b0000001, # 1 0b1001111, # 2 0b0010010, # 3 0b0000110, # 4 0b1001100, # 5 0b0100100, # 6 0b0100000, # 7 0b0001111, # 8 0b0000000, # 9 0b0000100, ] Switch(self.dataIn) \ .addCases(enumerate([self.dataOut(v) for v in dec])) \ .Default( # display off when value is out of range self.dataOut(0b1111111) )
def _impl(self): st_t = HEnum("state_t", ["IDLE", "LOAD_SR", "CONVERTING", "DONE"]) st = self._reg("st", st_t, def_val=st_t.IDLE) sr_shift = st.next._eq(st_t.CONVERTING) bcd = self.din bin_ = self.dout bcd_sr = self._reg("bcd_sr", bcd.data._dtype, def_val=0) binary_sr = self._reg("binary_sr", bin_.data._dtype, def_val=0) next_bcd = rename_signal(self, bcd_sr >> 1, "next_bcd") MAX_COUNT = binary_sr._dtype.bit_length() bit_count = self._reg("bit_count", Bits(log2ceil(MAX_COUNT), signed=False), def_val=MAX_COUNT) If(sr_shift, bit_count(bit_count - 1), ).Else( bit_count(MAX_COUNT), ) # dabble the digits digits = [] for i in range(self.BCD_DIGITS): d = next_bcd[(i + 1) * 4:i * 4]._unsigned() d_sig = (d < 7)._ternary(d, d - 3) digits.append(d_sig) If(st.next._eq(st_t.LOAD_SR), bcd_sr(bcd.data), binary_sr(0), ).Elif(sr_shift, # shift right binary_sr(Concat(bcd_sr[0], binary_sr[:1])), bcd_sr(Concat(*reversed(digits))), ) bin_.data(binary_sr) Switch(st)\ .Case(st_t.IDLE, If(bcd.vld, st(st_t.LOAD_SR), # load the shift registers ))\ .Case(st_t.LOAD_SR, # shift right each cycle st(st_t.CONVERTING), )\ .Case(st_t.CONVERTING, If(bit_count._eq(0), # indicate completion st(st_t.DONE), ) )\ .Case(st_t.DONE, If(bcd.vld & bin_.rd, st(st_t.LOAD_SR), ).Elif(bin_.rd, st(st_t.IDLE), ) ) bcd.rd(st._eq(st_t.IDLE) | (st._eq(st_t.DONE) & bin_.rd)) bin_.vld(st._eq(st_t.DONE))
def _impl(self) -> None: start = self._sig("start") part_res_t = Bits(self.DATA_WIDTH) # High-order n bits of product a = self._reg("a", part_res_t) # multiplicand m = self._reg("m", part_res_t) # Initially holds multiplier, ultimately holds low-order n bits of product q = self._reg("q", part_res_t) # previous bit 0 of q q_1 = self._reg("q_1") din = self.dataIn dout = self.dataOut counter = self._reg( "counter", Bits(log2ceil(self.DATA_WIDTH + 1), signed=False), def_val=0) done = counter._eq(0) waitinOnConsumer = self._reg("waitinOnConsumer", def_val=0) add = rename_signal(self, (a + m)._signed(), "add") sub = rename_signal(self, (a - m)._signed(), "sub") If(start, a(0), m(din.a), q(din.b), q_1(0), counter(self.DATA_WIDTH), ).Elif(~done, Switch(Concat(q[0], q_1)) .Case(0b01, # add multiplicand to left half of product a(add >> 1), q(Concat(add[0], q[:1])), ).Case(0b10, # substract multiplicand from left half of product a(sub >> 1), q(Concat(sub[0], q[:1])), ).Default( a(a._signed() >> 1), q(Concat(a[0], q[:1])), ), q_1(q[0]), counter(counter - 1) ) If(start, waitinOnConsumer(1) ).Elif(done & dout.rd, waitinOnConsumer(0), ) dout.data(Concat(a, q)._vec()) dout.vld(done & waitinOnConsumer) start(din.vld & done & ~waitinOnConsumer) din.rd(done & ~waitinOnConsumer)
def _impl(self): self._parseTemplate() bus = self.bus ADDR_STEP = self._getAddrStep() if self._directly_mapped_words: readReg = self._reg("readReg", dtype=bus.dout._dtype) # tuples (condition, assign statements) If(bus.en, self.connect_directly_mapped_read(bus.addr, readReg, []) ) self.connect_directly_mapped_write(bus.addr, bus.din, bus.en & bus.we) else: readReg = None if self._bramPortMapped: BRAMS_CNT = len(self._bramPortMapped) bramIndxCases = [] readBramIndx = self._reg("readBramIndx", Bits( log2ceil(BRAMS_CNT + 1), False)) outputSwitch = Switch(readBramIndx) for i, ((_, _), t) in enumerate(self._bramPortMapped): # if we can use prefix instead of addr comparing do it _addr = t.bitAddr // ADDR_STEP _addrEnd = t.bitAddrEnd // ADDR_STEP port = self.getPort(t) _addrVld, _ = self.propagateAddr(bus.addr, ADDR_STEP, port.addr, port.dout._dtype.bit_length(), t) port.we(bus.en & bus.we & _addrVld) port.en(bus.en & _addrVld) port.din(bus.din) bramIndxCases.append((_addrVld, readBramIndx(i))) outputSwitch.Case(i, bus.dout(port.dout)) outputSwitch.Default(bus.dout(readReg)) SwitchLogic(bramIndxCases, default=readBramIndx(BRAMS_CNT)) else: bus.dout(readReg)
def test_Switch(self): ctx = RtlNetlist() a = ctx.sig("a", uint8_t) b = ctx.sig("b", uint8_t) stm = Switch(a)\ .Case(0, b(0))\ .Case(1, b(1))\ .Case(2, b(2))\ .Default(b(3)) self.ae(stm, """\ Switch(a)\\ .Case(0, b(0))\\ .Case(1, b(1))\\ .Case(2, b(2))\\ .Default( b(3))""")
def remSizeToStrb(self, remSize, strb): strbBytes = 2**self.getSizeAlignBits() return Switch(remSize)\ .Case(0, strb(mask(strbBytes)) ).addCases( [(i + 1, strb(mask(i + 1))) for i in range(strbBytes - 1)] )
def _impl(self): Switch(self.sel)\ .Case(0, self.out(self.a) ).Case(1, self.out(self.b) ).Case(2, self.out(self.c) ).Default( self.out(0) )
def SwitchStatement(): t = Bits(8) n = RtlNetlist() In = n.sig("input", t, defVal=8) Out = n.sig("output", t) Switch(In).addCases([(i, Out(i + 1)) for i in range(8)]) interf = [In, Out] return n, interf
def SwitchStatement(): t = Bits(8) n = RtlNetlist() In = n.sig("input", t, def_val=8) Out = n.sig("output", t) Switch(In).add_cases([(i, Out(i + 1)) for i in range(8)]) interf = {In: DIRECTION.IN, Out: DIRECTION.OUT} return n, interf
def connect_directly_mapped_read(self, ar_addr: RtlSignal, r_data: RtlSignal, default_r_data_drive): """ Connect the RegCntrl.din interfaces to a bus """ DW = int(self.DATA_WIDTH) ADDR_STEP = self._getAddrStep() directlyMappedWords = [] for (w_i, items) in self._directly_mapped_words: w_data = [] last_end = w_i * DW for tpart in items: assert last_end == tpart.startOfPart, (last_end, tpart.startOfPart) if tpart.tmpl is None: # padding din = Bits(tpart.bit_length()).from_py(None) else: din = self.getPort(tpart.tmpl) if isinstance(din, RegCntrl): din = din.din if din._dtype.bit_length() > 1: fr = tpart.getFieldBitRange() din = din[fr[0]:fr[1]] w_data.append(din) last_end = tpart.endOfPart end_of_word = (w_i + 1) * DW assert last_end == end_of_word, (last_end, end_of_word) word_val = Concat(*reversed(w_data)) assert word_val._dtype.bit_length() == DW, (items, word_val) directlyMappedWords.append((w_i * (DW // ADDR_STEP), word_val)) mux = Switch(ar_addr).add_cases([ (word_i, r_data(val)) for (word_i, val) in directlyMappedWords ]) if default_r_data_drive: mux.Default(default_r_data_drive) return mux
def _impl(self): V = self.VAL VAL_W = self.VAL._dtype.bit_length() D_W = self.DATA_WIDTH if not V._is_full_valid(): raise NotImplementedError() din = self.dataIn dout = self.dataOut if VAL_W <= D_W: # do comparison in single word dout.data(din.data[VAL_W:]._eq(V)) StreamNode([din], [dout]).sync() else: # build fsm for comparing word_cnt = ceil(VAL_W / D_W) word_index = self._reg("word_index", Bits(log2ceil(word_cnt - 1)), def_val=0) # true if all previous words were matching state = self._reg("state", def_val=1) offset = 0 word_cases = [] for is_last_word, i in iter_with_last(range(word_cnt)): val_low = offset val_high = min(offset + D_W, VAL_W) in_high = val_high - val_low state_update = din.data[in_high:]._eq(V[val_high:val_low]) if is_last_word: dout.data(state & state_update) else: word_cases.append((i, state(state & state_update))) If(StreamNode([din], [dout]).ack(), If(din.last, word_index(0), state(1), ).Else( word_index(word_index + 1), Switch(word_index)\ .add_cases(word_cases) ) ) StreamNode([din], [dout], extraConds={ dout: din.valid & din.last }, skipWhen={ dout: ~(din.valid & din.last) }).sync()
def downscale(self, IN_DW, OUT_DW): if IN_DW % OUT_DW != 0: raise NotImplementedError() dOut = self.getDataWidthDependent(self.dataOut) # instantiate AxiSReg, AxiSBuilder is not used to avoid dependencies inReg = AxiSReg(self.intfCls) inReg._updateParamsFrom(self.dataIn) self.inReg = inReg inReg.clk(self.clk) inReg.rst_n(self.rst_n) inReg.dataIn(self.dataIn) dataIn = inReg.dataOut dIn = self.getDataWidthDependent(dataIn) ITEMS = IN_DW // OUT_DW itemCntr = self._reg("itemCntr", Bits(log2ceil(ITEMS + 1)), def_val=0) hs = StreamNode([dataIn], [self.dataOut]).ack() isLastItem = itemCntr._eq(ITEMS - 1) strbLastOverride = self.nextAreNotValidLogic(dataIn.strb, itemCntr, ITEMS, OUT_DW) if strbLastOverride is not True: isLastItem = isLastItem | strbLastOverride # connected item selected by itemCntr to output for inp, outp in zip(dIn, dOut): w = outp._dtype.bit_length() Switch(itemCntr)\ .add_cases([ (wordIndx, outp(inp[((wordIndx + 1) * w):(w * wordIndx)])) for wordIndx in range(ITEMS) ])\ .Default( outp(None) ) # connect others signals directly for inp, outp in zip(self.get_data(dataIn), self.get_data(self.dataOut)): if inp not in dIn and inp is not dataIn.last: outp(inp) self.dataOut.last(dataIn.last & isLastItem) self.get_ready_signal(dataIn)(self.get_ready_signal(self.dataOut) & isLastItem & dataIn.valid) self.get_valid_signal(self.dataOut)(self.get_valid_signal(dataIn)) If(hs, If(isLastItem, itemCntr(0)).Else(itemCntr(itemCntr + 1)))
def ComplexConditions(): n = RtlNetlist() stT = HEnum('t_state', ["idle", "tsWait", "ts0Wait", "ts1Wait", "lenExtr"]) clk = n.sig('clk') rst = n.sig("rst") st = n.sig('st', stT, clk=clk, syncRst=rst, def_val=stT.idle) s_idle = n.sig('s_idle') sd0 = n.sig('sd0') sd1 = n.sig('sd1') cntrlFifoVld = n.sig('ctrlFifoVld') cntrlFifoLast = n.sig('ctrlFifoLast') def tsWaitLogic(ifNoTsRd): return If(sd0 & sd1, st(stT.lenExtr)).Elif(sd0, st(stT.ts1Wait)).Elif( sd1, st(stT.ts0Wait)).Else(ifNoTsRd) Switch(st)\ .Case(stT.idle, tsWaitLogic( If(cntrlFifoVld, st(stT.tsWait) ) ) ).Case(stT.tsWait, tsWaitLogic(st(st)) ).Case(stT.ts0Wait, If(sd0, st(stT.lenExtr) ) ).Case(stT.ts1Wait, If(sd1, st(stT.lenExtr) ) ).Case(stT.lenExtr, If(cntrlFifoVld & cntrlFifoLast, st(stT.idle) ) ) s_idle(st._eq(stT.idle)) return n, { rst: DIRECTION.IN, clk: DIRECTION.IN, sd0: DIRECTION.IN, sd1: DIRECTION.IN, cntrlFifoVld: DIRECTION.IN, cntrlFifoLast: DIRECTION.IN, s_idle: DIRECTION.OUT }
def _impl(self): assert (int(self.USER_WIDTH) == 2) # this is how is protocol specified In = self.dataIn Out = self.dataOut propagateClkRstn(self) lastSeenLast = self._reg("lastSeenLast", defVal=1) sof = lastSeenLast Out.data(In.data) Out.src_rdy_n(~In.valid) outRd = ~Out.dst_rdy_n If(In.valid & outRd, lastSeenLast(In.last)) In.ready(outRd) Out.eof_n(~In.last) # AXI_USER(0) -> FL_SOP_N # Always set FL_SOP_N when FL_SOF_N - added for compatibility with xilinx # axi components. Otherwise FL_SOP_N would never been set and LocalLink # protocol would be broken. sop = In.user[0] If(sof, Out.sop_n(0)).Else(Out.sop_n(~sop)) # AXI_USER(1) -> FL_EOP_N # Always set FL_EOP_N when FL_EOF_N - added for compatibility with xilinx # axi components. Otherwise FL_EOP_N would never been set and LocalLink # protocol would be broken. eop = In.user[1] If(In.last, Out.eop_n(0)).Else(Out.eop_n(~eop)) remMap = [] remBits = Out.rem._dtype.bit_length() strbBits = In.strb._dtype.bit_length() for strb, rem in strbToRem(strbBits, remBits): remMap.append((strb, Out.rem(rem))) end_of_part_or_transaction = In.last | eop If(end_of_part_or_transaction, Switch(In.strb)\ .addCases(remMap) ).Else( Out.rem(mask(remBits)) ) Out.sof_n(~sof)
def _impl(self): self.DATA_WIDTH = int(self.DATA_WIDTH) vldAll = mask(self.DATA_WIDTH // 8) dout = self.dataOut DATA_LEN = len(self.DATA) wordIndex_w = int(math.log2(DATA_LEN) + 1) wordIndex = self._reg("wordIndex", Bits(wordIndex_w), def_val=0) Switch(wordIndex)\ .add_cases([(i, dout.data(d)) for i, d in enumerate(self.DATA)])\ .Default(dout.data(None)) dout.last(wordIndex._eq(DATA_LEN - 1)) If(wordIndex < DATA_LEN, dout.strb(vldAll), dout.valid(1)).Else(dout.strb(None), dout.valid(0)) If(self.dataRd(), self.nextWordIndexLogic(wordIndex))
def _impl(self): self.DATA_WIDTH = int(self.DATA_WIDTH) dout = self.dataOut DATA_LEN = len(self.DATA) wordIndex_w = int(math.log2(DATA_LEN) + 1) wordIndex = self._reg("wordIndex", Bits(wordIndex_w), def_val=0) def set_data(d): return self.set_data(dout, d) Switch(wordIndex)\ .add_cases([(i, set_data(d)) for i, d in enumerate(self.DATA)])\ .Default(*set_data(None)) If(wordIndex < DATA_LEN, dout.vld(1)).Else(dout.vld(0)) If(self.dataRd(), self.nextWordIndexLogic(wordIndex))
def _impl(self): propagateClkRstn(self) ITEM_WIDTH = int(self.ITEM_WIDTH) DATA_WIDTH = int(self.DATA_WIDTH) ITEMS_IN_DATA_WORD = self.ITEMS_IN_DATA_WORD ITEM_SIZE_IN_WORDS = 1 if ITEM_WIDTH % 8 != 0 or ITEM_SIZE_IN_WORDS * DATA_WIDTH != ITEMS_IN_DATA_WORD * ITEM_WIDTH: raise NotImplementedError(ITEM_WIDTH) req = self.rDatapump.req req.id(self.ID) req.len(ITEM_SIZE_IN_WORDS - 1) req.rem(0) if ITEMS_IN_DATA_WORD == 1: addr = Concat(self.index.data, vec(0, log2ceil(ITEM_WIDTH // 8))) req.addr(self.base + fitTo(addr, req.addr)) StreamNode(masters=[self.index], slaves=[req]).sync() self.item.data(self.rDatapump.r.data) StreamNode(masters=[self.rDatapump.r], slaves=[self.item]).sync() else: r = self.rDatapump.r.data f = self.itemSubIndexFifo subIndexBits = f.dataIn.data._dtype.bit_length() itemAlignBits = log2ceil(ITEM_WIDTH // 8) addr = Concat(self.index.data[:subIndexBits], vec(0, itemAlignBits + subIndexBits)) req.addr(self.base + fitTo(addr, req.addr)) f.dataIn.data(self.index.data[subIndexBits:]) StreamNode(masters=[self.index], slaves=[req, f.dataIn]).sync() Switch(f.dataOut.data).addCases([ (ITEMS_IN_DATA_WORD - i - 1, self.item.data(r[(ITEM_WIDTH * (i + 1)):(ITEM_WIDTH * i)])) for i in range(ITEMS_IN_DATA_WORD) ]) StreamNode(masters=[self.rDatapump.r, f.dataOut], slaves=[self.item]).sync()
def handler_data_mux(self, dataOut_channels, dataIn_channels, order_din_index_for_dout): for out_i, (dataOut, order_s_for_m) in enumerate( zip(dataOut_channels, order_din_index_for_dout)): if order_s_for_m is None: connected_in = self.OUTPUTS[out_i] assert len(connected_in) == 1, connected_in connected_in = list(connected_in)[0] dataOut(dataIn_channels[connected_in], exclude={dataOut.valid, dataOut.ready}) else: cases = [] for si, s in enumerate(dataIn_channels): cases.append((si, dataOut(s, exclude={s.valid, s.ready}))) Switch(order_s_for_m.data)\ .add_cases(cases)\ .Default( s(None) for s in dataOut._interfaces if s not in {dataOut.valid, dataOut.ready} )
def test_ifsInSwitch(self): n = self.n stT = HEnum('t_state', ["idle", "tsWait", "ts0Wait", "ts1Wait", "lenExtr"]) clk = n.sig('clk') rst = n.sig("rst") st = n.sig('st', stT, clk=clk, syncRst=rst, defVal=stT.idle) sd0 = n.sig('sd0') sd1 = n.sig('sd1') cntrlFifoVld = n.sig('ctrlFifoVld') cntrlFifoLast = n.sig('ctrlFifoLast') def tsWaitLogic(): return If(sd0 & sd1, c(stT.lenExtr, st) ).Else( c(stT.ts1Wait, st) ) obj = Switch(st)\ .Case(stT.idle, tsWaitLogic() ).Case(stT.tsWait, tsWaitLogic() ).Case(stT.ts0Wait, If(sd0, c(stT.lenExtr, st) ).Else( c(st, st) ) ).Case(stT.ts1Wait, If(sd1, c(stT.lenExtr, st) ).Else( c(st, st) ) ).Case(stT.lenExtr, If(cntrlFifoVld & cntrlFifoLast, c(stT.idle, st) ).Else( c(st, st) ) ) cont, io_change = obj._try_reduce() self.assertFalse(io_change) self.assertEqual(len(cont), 1) cont = cont[0] tmpl = """ CASE st IS WHEN idle => IF (sd0 AND sd1) = '1' THEN st_next <= lenExtr; ELSE st_next <= ts1Wait; END IF; WHEN tsWait => IF (sd0 AND sd1) = '1' THEN st_next <= lenExtr; ELSE st_next <= ts1Wait; END IF; WHEN ts0Wait => IF sd0 = '1' THEN st_next <= lenExtr; ELSE st_next <= st; END IF; WHEN ts1Wait => IF sd1 = '1' THEN st_next <= lenExtr; ELSE st_next <= st; END IF; WHEN OTHERS => IF (ctrlFifoVld AND ctrlFifoLast) = '1' THEN st_next <= idle; ELSE st_next <= st; END IF; END CASE """ self.strStructureCmp(cont, tmpl)