def __init__(self, phy, clk_freq, mode): # etherbone self.submodules.etherbone = etherbone = Etherbone(mode) # packetizer / depacketizer depacketizer = Depacketizer(clk_freq) packetizer = Packetizer() self.submodules += depacketizer, packetizer # fifos tx_fifo = stream.SyncFIFO([("data", 32)], 16) rx_fifo = stream.SyncFIFO([("data", 32)], 16) self.submodules += tx_fifo, rx_fifo # modules connection self.comb += [ # core --> phy packetizer.source.connect(tx_fifo.sink), tx_fifo.source.connect(phy.sink), # phy --> core phy.source.connect(rx_fifo.sink), rx_fifo.source.connect(depacketizer.sink), # etherbone <--> core depacketizer.source.connect(etherbone.sink), etherbone.source.connect(packetizer.sink) ]
def __init__(self, buffer_depth=256): self.sink = sink = stream.Endpoint(etherbone_mmap_description(32)) self.source = source = stream.Endpoint( etherbone_record_description(32)) # # # pbuffer = stream.SyncFIFO(etherbone_mmap_description(32), buffer_depth, buffered=True) self.submodules += pbuffer self.comb += sink.connect(pbuffer.sink) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", pbuffer.source.ack.eq(1), If(pbuffer.source.stb, pbuffer.source.ack.eq(0), NextState("SEND_BASE_ADDRESS"))) self.comb += [ source.byte_enable.eq(pbuffer.source.be), If(pbuffer.source.we, source.wcount.eq(pbuffer.source.count)).Else( source.rcount.eq(pbuffer.source.count)) ] fsm.act("SEND_BASE_ADDRESS", source.stb.eq(pbuffer.source.stb), source.eop.eq(0), source.data.eq(pbuffer.source.base_addr), If(source.ack, NextState("SEND_DATA"))) fsm.act( "SEND_DATA", source.stb.eq(pbuffer.source.stb), source.eop.eq(pbuffer.source.eop), source.data.eq(pbuffer.source.data), If(source.stb & source.ack, pbuffer.source.ack.eq(1), If(source.eop, NextState("IDLE"))))
def __init__(self, kcsrs, rtio_counter, membus, fifo_depth=128): # shutdown procedure: set enable to 0, wait until busy=0 self.enable = CSRStorage() self.busy = CSRStatus() self.submodules.message_encoder = MessageEncoder( kcsrs, rtio_counter, self.enable.storage) self.submodules.fifo = stream.SyncFIFO([("data", message_len)], fifo_depth, True) self.submodules.converter = stream.Converter( message_len, len(membus.dat_w), reverse=True, report_valid_token_count=True) self.submodules.dma = DMAWriter(membus) enable_r = Signal() self.sync += [ enable_r.eq(self.enable.storage), If(self.enable.storage & ~enable_r, self.busy.status.eq(1)), If(self.dma.sink.stb & self.dma.sink.ack & self.dma.sink.eop, self.busy.status.eq(0)) ] self.comb += [ self.message_encoder.source.connect(self.fifo.sink), self.fifo.source.connect(self.converter.sink), self.converter.source.connect(self.dma.sink) ]
def __init__(self, buffer_depth=256): self.sink = sink = stream.Endpoint(etherbone_record_description(32)) self.source = source = stream.Endpoint(etherbone_mmap_description(32)) # # # fifo = stream.SyncFIFO(etherbone_record_description(32), buffer_depth, buffered=True) self.submodules += fifo self.comb += sink.connect(fifo.sink) base_addr = Signal(32) base_addr_update = Signal() self.sync += If(base_addr_update, base_addr.eq(fifo.source.data)) counter = Signal(max=512) counter_reset = Signal() counter_ce = Signal() self.sync += \ If(counter_reset, counter.eq(0) ).Elif(counter_ce, counter.eq(counter + 1) ) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act( "IDLE", fifo.source.ack.eq(1), counter_reset.eq(1), If( fifo.source.stb, base_addr_update.eq(1), If(fifo.source.wcount, NextState("RECEIVE_WRITES")).Elif( fifo.source.rcount, NextState("RECEIVE_READS")))) fsm.act( "RECEIVE_WRITES", source.stb.eq(fifo.source.stb), source.eop.eq(counter == fifo.source.wcount - 1), source.count.eq(fifo.source.wcount), source.be.eq(fifo.source.byte_enable), source.addr.eq(base_addr[2:] + counter), source.we.eq(1), source.data.eq(fifo.source.data), fifo.source.ack.eq(source.ack), If( source.stb & source.ack, counter_ce.eq(1), If( source.eop, If(fifo.source.rcount, NextState("RECEIVE_BASE_RET_ADDR")).Else( NextState("IDLE"))))) fsm.act( "RECEIVE_BASE_RET_ADDR", counter_reset.eq(1), If(fifo.source.stb, base_addr_update.eq(1), NextState("RECEIVE_READS"))) fsm.act( "RECEIVE_READS", source.stb.eq(fifo.source.stb), source.eop.eq(counter == fifo.source.rcount - 1), source.count.eq(fifo.source.rcount), source.base_addr.eq(base_addr), source.addr.eq(fifo.source.data[2:]), fifo.source.ack.eq(source.ack), If(source.stb & source.ack, counter_ce.eq(1), If(source.eop, NextState("IDLE"))))
def __init__(self, crc_class, layout): self.sink = sink = stream.Endpoint(layout) self.source = source = stream.Endpoint(layout) # # # dw = len(sink.data) crc = crc_class(dw) self.submodules += crc ratio = crc.width//dw fifo = ResetInserter()(stream.SyncFIFO(layout, ratio + 1)) self.submodules += fifo fsm = FSM(reset_state="RESET") self.submodules += fsm fifo_in = Signal() fifo_out = Signal() fifo_full = Signal() self.comb += [ fifo_full.eq(fifo.fifo.level == ratio), fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), fifo_out.eq(source.stb & source.ack), sink.connect(fifo.sink), fifo.sink.stb.eq(fifo_in), self.sink.ack.eq(fifo_in), source.stb.eq(sink.stb & fifo_full), source.eop.eq(sink.eop), fifo.source.ack.eq(fifo_out), source.payload.eq(fifo.source.payload), source.error.eq(sink.error | crc.error), ] fsm.act("RESET", crc.reset.eq(1), fifo.reset.eq(1), NextState("IDLE"), ) self.comb += crc.data.eq(sink.data) fsm.act("IDLE", If(sink.stb & sink.ack, crc.ce.eq(1), NextState("COPY") ) ) fsm.act("COPY", If(sink.stb & sink.ack, crc.ce.eq(1), If(sink.eop, NextState("RESET") ) ) )
def __init__(self): self.write_stb = write_stb = CSR() self.write_ack = write_ack = CSRStatus() self.write_data = write_data = CSRStorage(32) self.read_stb = read_stb = CSRStatus() self.read_ack = read_ack = CSR() self.read_data = read_data = CSRStatus(32) # # # fifo = stream.SyncFIFO([("data", 32)], 512, buffered=True) self.submodules += fifo self.comb += [ # Connect registers to FIFO Sink fifo.sink.stb.eq(write_stb.re), write_ack.status.eq(fifo.sink.ack), fifo.sink.data.eq(write_data.storage), # Connect FIFO Source to registers read_stb.status.eq(fifo.source.stb), fifo.source.ack.eq(read_ack.re), read_data.status.eq(fifo.source.data) ]
def __init__(self, bus, nbits_source=None, fifo_depth=None): ar, r = operator.attrgetter("ar", "r")(bus) dw = bus.data_width alignment_bits = bits_for(dw // 8) - 1 if nbits_source: if nbits_source % 8: raise ValueError("nbits_source must be a multiple of 8") if nbits_source > dw: raise ValueError("nbits_source must be <= bus.data_width") nbits_source = nbits_source or dw counter_bits = bits_for( (2**len(bus.ar.addr) - 1) // (nbits_source // 8)) self.sink = stream.Endpoint( pipe(rec_layout(ar, {"addr"}), juxt([ identity, R.always([("n", counter_bits)]), ]), concat, list)) self.source = stream.Endpoint([("data", nbits_source)]) ### sink_consume = Signal() self.comb += sink_consume.eq(self.sink.stb & self.sink.ack) remaining = Countdown(counter_bits) self.submodules += remaining self.comb += [ remaining.count_w.eq(self.sink.n), remaining.we.eq(sink_consume), remaining.ce.eq(self.source.stb & self.source.ack), ] eop_consumed = Signal() self.sync += [ If( sink_consume, eop_consumed.eq(0), ).Elif(self.source.stb & self.source.ack & self.source.eop, eop_consumed.eq(1)) ] converter = stream.Converter(dw, nbits_source) self.submodules += converter self.comb += [ converter.source.ack.eq(self.source.ack | eop_consumed), self.source.stb.eq(converter.source.stb & ~eop_consumed), self.source.eop.eq(remaining.done), self.source.data.eq(converter.source.data), ] fifo_depth = min(fifo_depth or BURST_LENGTH, BURST_LENGTH) if fifo_depth % (dw // 8): raise ValueError("fifo_depth shall be a multiple of wordsize") rfifo = stream.SyncFIFO(rec_layout(r, {"data"}), depth=fifo_depth) self.submodules += rfifo self.comb += rfifo.source.connect(converter.sink) burst_done = Signal() self.sync += burst_done.eq(r.valid & r.ready & r.last) # ar channel ar_acked = Signal(reset=1) sink_acked = Signal() self.sync += [ If(sink_consume, sink_acked.eq(1)).Elif(remaining.done, sink_acked.eq(0)) ] self.sync += [ If( sink_consume, ar_acked.eq(0), ar.addr[alignment_bits:].eq(self.sink.addr[alignment_bits:]), ).Else( If(burst_done & ~remaining.done, ar_acked.eq(0), ar.addr.eq(ar.addr + fifo_depth * dw // 8)), If(ar.valid & ar.ready, ar_acked.eq(1))), ] self.comb += [ self.sink.ack.eq(~sink_acked & remaining.done), ar.len.eq(fifo_depth - 1), ar.size.eq(burst_size(dw // 8)), ar.burst.eq(Burst.incr.value), # ensure FIFO is clear to not stall the bus ar.valid.eq(~ar_acked & ~rfifo.source.stb) ] # r channel self.comb += [ remaining.ce.eq(rfifo.sink.stb & rfifo.sink.ack), rfifo.sink.data.eq(r.data), rfifo.sink.stb.eq(r.valid), r.ready.eq(rfifo.sink.ack), ]
def __init__(self, bus, fifo_depth=None): aw, w, b = operator.attrgetter("aw", "w", "b")(bus) self.sink = stream.Endpoint( rec_layout(aw, {"addr"}) + rec_layout(w, {"data"})) ### dw = bus.data_width alignment_bits = bits_for(dw // 8) - 1 fifo_depth = min(fifo_depth or BURST_LENGTH, BURST_LENGTH) self.submodules.burst_cnt = Counter(fifo_depth - 1) sink_consume = Signal() self.comb += sink_consume.eq(self.sink.stb & self.sink.ack) sof = Signal(reset=1) # aw channel aw_acked = Signal() self.sync += [ If( sink_consume, sof.eq(self.sink.eop), If( sof, aw.addr[alignment_bits:].eq( self.sink.addr[alignment_bits:])).Elif( self.burst_cnt.done & aw_acked, aw.addr.eq(aw.addr + fifo_depth * dw // 8))) ] self.comb += [ aw.len.eq(fifo_depth - 1), aw.size.eq(burst_size(dw // 8)), aw.burst.eq(Burst.incr.value), ] self.sync += [ If(aw.valid & aw.ready, aw.valid.eq(0), aw_acked.eq(1)).Elif(sink_consume & ~aw_acked, aw.valid.eq(1)) ] # w channel wfifo = stream.SyncFIFO(rec_layout(w, {"data"}), depth=fifo_depth) self.submodules += wfifo self.comb += [ If(self.sink.eop, If(b.valid & b.ready, self.sink.ack.eq(1))).Else(self.sink.ack.eq(wfifo.sink.ack)) ] self.comb += [ wfifo.sink.stb.eq(self.sink.stb & (~self.sink.eop | (self.sink.eop & self.burst_cnt.running))), self.burst_cnt.ce.eq(wfifo.sink.stb & wfifo.sink.ack), wfifo.sink.eop.eq(self.burst_cnt.done), wfifo.sink.data.eq(self.sink.data), ] self.comb += [ w.data.eq(wfifo.source.data), w.strb.eq(2**(dw // 8) - 1), w.last.eq(wfifo.source.eop), ] self.comb += connect_source_hdshk(w, wfifo.source) # b channel self.sync += [ If( b.ready & b.valid, b.ready.eq(0), aw_acked.eq(0), ).Elif(reduce(operator.and_, [w.last, w.valid, w.ready]), b.ready.eq(1)) ]
def __init__(self, dw, depth, nslots=2): self.sink = sink = stream.Endpoint(eth_phy_layout(dw)) self.crc_error = Signal() slotbits = max(log2_int(nslots), 1) lengthbits = 32 self._slot = CSRStatus(slotbits) self._length = CSRStatus(lengthbits) self.submodules.ev = EventManager() self.ev.available = EventSourceLevel() self.ev.finalize() # # # # packet dropped if no slot available sink.ack.reset = 1 # length computation increment = Signal(3) self.comb += \ If(sink.last_be[3], increment.eq(1) ).Elif(sink.last_be[2], increment.eq(2) ).Elif(sink.last_be[1], increment.eq(3) ).Else( increment.eq(4) ) counter = Signal(lengthbits) counter_reset = Signal() counter_ce = Signal() self.sync += \ If(counter_reset, counter.eq(0) ).Elif(counter_ce, counter.eq(counter + increment) ) # slot computation slot = Signal(slotbits) slot_ce = Signal() self.sync += If(slot_ce, slot.eq(slot + 1)) ongoing = Signal() # status fifo fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots) self.submodules += fifo # fsm fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act( "IDLE", If( sink.stb, If(fifo.sink.ack, ongoing.eq(1), counter_ce.eq(1), NextState("WRITE")))) fsm.act( "WRITE", If( sink.stb, If(counter == eth_mtu, NextState("DISCARD_REMAINING")).Else( counter_ce.eq(1), ongoing.eq(1)), If( sink.eop, If((sink.error & sink.last_be) != 0, NextState("DISCARD")).Else(NextState("TERMINATE"))))) fsm.act("DISCARD", counter_reset.eq(1), NextState("IDLE")) fsm.act("DISCARD_REMAINING", If(sink.stb & sink.eop, NextState("TERMINATE"))) self.comb += [fifo.sink.slot.eq(slot), fifo.sink.length.eq(counter)] fsm.act("TERMINATE", counter_reset.eq(1), slot_ce.eq(1), fifo.sink.stb.eq(1), NextState("IDLE")) self.comb += [ fifo.source.ack.eq(self.ev.available.clear), self.ev.available.trigger.eq(fifo.source.stb), self._slot.status.eq(fifo.source.slot), self._length.status.eq(fifo.source.length), ] # memory mems = [None] * nslots ports = [None] * nslots for n in range(nslots): mems[n] = Memory(dw, depth) ports[n] = mems[n].get_port(write_capable=True) self.specials += ports[n] self.mems = mems cases = {} for n, port in enumerate(ports): cases[n] = [ ports[n].adr.eq(counter[2:]), ports[n].dat_w.eq(sink.data), If(sink.stb & ongoing, ports[n].we.eq(0xf)) ] self.comb += Case(slot, cases)
def __init__(self, dw, depth, nslots=2): self.source = source = stream.Endpoint(eth_phy_layout(dw)) slotbits = max(log2_int(nslots), 1) lengthbits = bits_for(depth * 4) # length in bytes self.lengthbits = lengthbits self._start = CSR() self._ready = CSRStatus() self._slot = CSRStorage(slotbits) self._length = CSRStorage(lengthbits) self.submodules.ev = EventManager() self.ev.done = EventSourcePulse() self.ev.finalize() # # # # command fifo fifo = stream.SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots) self.submodules += fifo self.comb += [ fifo.sink.stb.eq(self._start.re), fifo.sink.slot.eq(self._slot.storage), fifo.sink.length.eq(self._length.storage), self._ready.status.eq(fifo.sink.ack) ] # length computation counter = Signal(lengthbits) counter_reset = Signal() counter_ce = Signal() self.sync += \ If(counter_reset, counter.eq(0) ).Elif(counter_ce, counter.eq(counter + 4) ) # fsm last = Signal() last_d = Signal() fsm = FSM(reset_state="IDLE") self.submodules += fsm fsm.act("IDLE", counter_reset.eq(1), If(fifo.source.stb, NextState("CHECK"))) fsm.act("CHECK", If( ~last_d, NextState("SEND"), ).Else(NextState("END"), )) length_lsb = fifo.source.length[0:2] self.comb += [ If( last, If(length_lsb == 3, source.last_be.eq(0b0010)).Elif( length_lsb == 2, source.last_be.eq(0b0100)).Elif( length_lsb == 1, source.last_be.eq(0b1000)).Else( source.last_be.eq(0b0001))) ] fsm.act("SEND", source.stb.eq(1), source.eop.eq(last), If(source.ack, counter_ce.eq(~last), NextState("CHECK"))) fsm.act("END", fifo.source.ack.eq(1), self.ev.done.trigger.eq(1), NextState("IDLE")) # last computation self.comb += last.eq((counter + 4) >= fifo.source.length) self.sync += last_d.eq(last) # memory rd_slot = fifo.source.slot mems = [None] * nslots ports = [None] * nslots for n in range(nslots): mems[n] = Memory(dw, depth) ports[n] = mems[n].get_port() self.specials += ports[n] self.mems = mems cases = {} for n, port in enumerate(ports): self.comb += ports[n].adr.eq(counter[2:]) cases[n] = [source.data.eq(port.dat_r)] self.comb += Case(rd_slot, cases)