from liteeth.common import * from liteeth.generic.depacketizer import LiteEthDepacketizer from liteeth.generic.packetizer import LiteEthPacketizer class LiteEthEtherbonePacketPacketizer(LiteEthPacketizer): def __init__(self): LiteEthPacketizer.__init__(self, eth_etherbone_packet_description(32), eth_udp_user_description(32), etherbone_packet_header, etherbone_packet_header_len) class LiteEthEtherbonePacketTX(Module): def __init__(self, udp_port): self.sink = sink = Sink(eth_etherbone_packet_user_description(32)) self.source = source = Source(eth_udp_user_description(32)) ### self.submodules.packetizer = packetizer = LiteEthEtherbonePacketPacketizer() self.comb += [ packetizer.sink.stb.eq(sink.stb), packetizer.sink.sop.eq(sink.sop), packetizer.sink.eop.eq(sink.eop), sink.ack.eq(packetizer.sink.ack), packetizer.sink.magic.eq(etherbone_magic), packetizer.sink.port_size.eq(32//8), packetizer.sink.addr_size.eq(32//8), # XXX add a parameter? packetizer.sink.pf.eq(sink.pf), packetizer.sink.pr.eq(sink.pr), packetizer.sink.nr.eq(sink.nr), packetizer.sink.version.eq(etherbone_version), packetizer.sink.data.eq(sink.data) ] self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", packetizer.source.ack.eq(1), If(packetizer.source.stb & packetizer.source.sop, packetizer.source.ack.eq(0), NextState("SEND") ) ) fsm.act("SEND", Record.connect(packetizer.source, source), source.src_port.eq(0x1234), # XXX, source.dst_port.eq(udp_port), source.ip_address.eq(sink.ip_address), source.length.eq(sink.length + etherbone_packet_header_len), If(source.stb & source.eop & source.ack, NextState("IDLE") ) ) class LiteEthEtherbonePacketDepacketizer(LiteEthDepacketizer): def __init__(self): LiteEthDepacketizer.__init__(self, eth_udp_user_description(32), eth_etherbone_packet_description(32), etherbone_packet_header, etherbone_packet_header_len) class LiteEthEtherbonePacketRX(Module): def __init__(self): self.sink = sink = Sink(eth_udp_user_description(32)) self.source = source = Source(eth_etherbone_packet_user_description(32)) ### self.submodules.depacketizer = depacketizer = LiteEthEtherbonePacketDepacketizer() self.comb += Record.connect(sink, depacketizer.sink) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", depacketizer.source.ack.eq(1), If(depacketizer.source.stb & depacketizer.source.sop, depacketizer.source.ack.eq(0), NextState("CHECK") ) ) valid = Signal() self.sync += valid.eq( depacketizer.source.stb & (depacketizer.source.magic == etherbone_magic) ) fsm.act("CHECK", If(valid, NextState("PRESENT") ).Else( NextState("DROP") ) ) self.comb += [ source.sop.eq(depacketizer.source.sop), source.eop.eq(depacketizer.source.eop), source.pf.eq(depacketizer.source.pf), source.pr.eq(depacketizer.source.pr), source.nr.eq(depacketizer.source.nr), source.data.eq(depacketizer.source.data), source.src_port.eq(sink.src_port), source.dst_port.eq(sink.dst_port), source.ip_address.eq(sink.ip_address), source.length.eq(sink.length - etherbone_packet_header_len) ] fsm.act("PRESENT", source.stb.eq(depacketizer.source.stb), depacketizer.source.ack.eq(source.ack), If(source.stb & source.eop & source.ack, NextState("IDLE") ) ) fsm.act("DROP", depacketizer.source.ack.eq(1), If(depacketizer.source.stb & depacketizer.source.eop & depacketizer.source.ack, NextState("IDLE") ) ) class LiteEthEtherbonePacket(Module): def __init__(self, udp, udp_port): self.submodules.tx = tx = LiteEthEtherbonePacketTX(udp_port) self.submodules.rx = rx = LiteEthEtherbonePacketRX() udp_port = udp.crossbar.get_port(udp_port, dw=32) self.comb += [ Record.connect(tx.source, udp_port.sink), Record.connect(udp_port.source, rx.sink) ] self.sink, self.source = self.tx.sink, self.rx.source