r.append(f)
return r
+def eth_raw_description(dw):
+ payload_layout = [
+ ("data", dw),
+ ("error", dw//8)
+ ]
+ return EndpointDescription(payload_layout, packetized=True)
+
def eth_phy_description(dw):
payload_layout = [
("data", dw),
return EndpointDescription(payload_layout, param_layout, packetized=True)
def eth_etherbone_packet_user_description(dw):
- payload_layout = [("data", dw)]
+ payload_layout = [
+ ("data", dw),
+ ("error", dw//8)
+ ]
param_layout = _layout_from_header(etherbone_packet_header)
param_layout = _remove_from_layout(param_layout, "magic", "portsize", "addrsize", "version")
param_layout += eth_udp_user_description(dw).param_layout
return EndpointDescription(payload_layout, param_layout, packetized=True)
def eth_etherbone_record_description(dw):
- payload_layout = [("data", dw)]
+ payload_layout = [
+ ("data", dw),
+ ("error", dw//8)
+ ]
param_layout = _layout_from_header(etherbone_record_header)
return EndpointDescription(payload_layout, param_layout, packetized=True)
from liteeth.common import *
-from liteeth.core.etherbone import common
+
+from liteeth.generic.arbiter import Arbiter
+from liteeth.generic.dispatcher import Dispatcher
+
from liteeth.core.etherbone.packet import *
+from liteeth.core.etherbone.probe import *
+from liteeth.core.etherbone.record import *
class LiteEthEtherbone(Module):
def __init__(self, udp, udp_port):
self.submodules.packet = packet = LiteEthEtherbonePacket(udp, udp_port)
+ self.submodules.probe = probe = LiteEthEtherboneProbe()
+ self.submodules.record = record = LiteEthEtherboneRecord()
+
+ dispatcher = Dispatcher(packet.source, [probe.sink, record.sink])
+ self.comb += dispatcher.sel.eq(~packet.source.pf)
+ self.submodules += dispatcher
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- packet.source.ack.eq(1),
- If(packet.source.stb & packet.source.sop,
- If(packet.source.pf,
- packet.source.ack.eq(0),
- NextState("SEND_PROBE_RESPONSE")
- )
- )
- )
- fsm.act("SEND_PROBE_RESPONSE",
- packet.sink.stb.eq(1),
- packet.sink.sop.eq(1),
- packet.sink.eop.eq(1),
- packet.sink.pr.eq(1),
- packet.sink.ip_address.eq(packet.source.ip_address),
- packet.sink.length.eq(0),
- If(packet.sink.ack,
- packet.source.ack.eq(1),
- NextState("IDLE")
- )
- )
+ arbiter = Arbiter([probe.source, record.source], packet.sink)
+ self.submodules += arbiter
+++ /dev/null
-from liteeth.common import *
from liteeth.common import *
-from liteeth.core.etherbone import common
class LiteEthEtherboneWishboneMaster(Module):
def __init__(self):
from liteeth.common import *
from liteeth.generic.depacketizer import LiteEthDepacketizer
from liteeth.generic.packetizer import LiteEthPacketizer
-from liteeth.core.etherbone import common
class LiteEthEtherbonePacketPacketizer(LiteEthPacketizer):
def __init__(self):
--- /dev/null
+from liteeth.common import *
+
+class LiteEthEtherboneProbe(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
+ self.source = source = Source(eth_etherbone_packet_user_description(32))
+
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+
+ fsm.act("IDLE",
+ sink.ack.eq(1),
+ If(sink.stb & sink.sop,
+ sink.ack.eq(0),
+ NextState("PROBE_RESPONSE")
+ )
+ )
+ fsm.act("PROBE_RESPONSE",
+ Record.connect(sink, source),
+ source.pf.eq(0),
+ source.pr.eq(1),
+ If(source.stb & source.eop & source.ack,
+ NextState("IDLE")
+ )
+ )
--- /dev/null
+from liteeth.common import *
+from liteeth.generic.depacketizer import LiteEthDepacketizer
+from liteeth.generic.packetizer import LiteEthPacketizer
+
+class LiteEthEtherboneRecordPacketizer(LiteEthPacketizer):
+ def __init__(self):
+ LiteEthPacketizer.__init__(self,
+ eth_etherbone_record_description(32),
+ eth_raw_description(32),
+ etherbone_record_header,
+ etherbone_record_header_len)
+
+class LiteEthEtherboneRecordTX(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_etherbone_record_description(32))
+ self.source = source = Source(eth_raw_description(32))
+ ###
+ self.submodules.packetizer = packetizer = LiteEthEtherboneRecordPacketizer()
+ self.comb += Record.connect(sink, packetizer.sink)
+
+ 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),
+ If(source.stb & source.eop & source.ack,
+ NextState("IDLE")
+ )
+ )
+
+class LiteEthEtherboneRecordDepacketizer(LiteEthDepacketizer):
+ def __init__(self):
+ LiteEthDepacketizer.__init__(self,
+ eth_raw_description(32),
+ eth_etherbone_record_description(32),
+ etherbone_record_header,
+ etherbone_record_header_len)
+
+class LiteEthEtherboneRecordRX(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_raw_description(32))
+ self.source = source = Source(eth_etherbone_record_description(32))
+ ###
+ self.submodules.depacketizer = depacketizer = LiteEthEtherboneRecordDepacketizer()
+ 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(1) # XXX
+ fsm.act("CHECK",
+ If(valid,
+ NextState("PRESENT")
+ ).Else(
+ NextState("DROP")
+ )
+ )
+ fsm.act("PRESENT",
+ Record.connect(depacketizer.source, source),
+ 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 LiteEthEtherboneRecord(Module):
+ def __init__(self):
+ self.sink = sink = Sink(eth_etherbone_packet_user_description(32))
+ self.source = source = Sink(eth_etherbone_packet_user_description(32))
+ ###
+ self.submodules.record_tx = record_tx = LiteEthEtherboneRecordTX()
+ self.submodules.record_rx = record_rx = LiteEthEtherboneRecordRX()
###
dw = flen(sink.data)
+ header_words = (header_length*8)//dw
+
shift = Signal()
- counter = Counter(max=header_length//(dw//8))
+ counter = Counter(max=max(header_words, 2))
self.submodules += counter
- self.sync += \
- If(shift,
- self.header.eq(Cat(self.header[dw:], sink.data))
- )
+ if header_words == 1:
+ self.sync += \
+ If(shift,
+ self.header.eq(sink.data)
+ )
+ else:
+ self.sync += \
+ If(shift,
+ self.header.eq(Cat(self.header[dw:], sink.data))
+ )
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
+ if header_words == 1:
+ idle_next_state = "COPY"
+ else:
+ idle_next_state = "RECEIVE_HEADER"
+
fsm.act("IDLE",
sink.ack.eq(1),
counter.reset.eq(1),
If(sink.stb,
shift.eq(1),
- NextState("RECEIVE_HEADER")
+ NextState(idle_next_state)
)
)
- fsm.act("RECEIVE_HEADER",
- sink.ack.eq(1),
- If(sink.stb,
- counter.ce.eq(1),
- shift.eq(1),
- If(counter.value == header_length//(dw//8)-2,
- NextState("COPY")
+ if header_words != 1:
+ fsm.act("RECEIVE_HEADER",
+ sink.ack.eq(1),
+ If(sink.stb,
+ counter.ce.eq(1),
+ shift.eq(1),
+ If(counter.value == header_words-2,
+ NextState("COPY")
+ )
)
)
- )
no_payload = Signal()
self.sync += \
If(fsm.before_entering("COPY"),
dw = flen(self.sink.data)
header_reg = Signal(header_length*8)
+ header_words = (header_length*8)//dw
load = Signal()
shift = Signal()
- counter = Counter(max=header_length//(dw//8))
+ counter = Counter(max=max(header_words, 2))
self.submodules += counter
self.comb += _encode_header(header_type, self.header, sink)
- self.sync += [
- If(load,
- header_reg.eq(self.header)
- ).Elif(shift,
- header_reg.eq(Cat(header_reg[dw:], Signal(dw)))
- )
- ]
+ if header_words == 1:
+ self.sync += [
+ If(load,
+ header_reg.eq(self.header)
+ )
+ ]
+ else:
+ self.sync += [
+ If(load,
+ header_reg.eq(self.header)
+ ).Elif(shift,
+ header_reg.eq(Cat(header_reg[dw:], Signal(dw)))
+ )
+ ]
fsm = FSM(reset_state="IDLE")
self.submodules += fsm
+ if header_words == 1:
+ idle_next_state = "COPY"
+ else:
+ idle_next_state = "SEND_HEADER"
+
fsm.act("IDLE",
sink.ack.eq(1),
counter.reset.eq(1),
source.data.eq(self.header[:dw]),
If(source.stb & source.ack,
load.eq(1),
- NextState("SEND_HEADER"),
+ NextState(idle_next_state)
)
)
)
- fsm.act("SEND_HEADER",
- source.stb.eq(1),
- source.sop.eq(0),
- source.eop.eq(sink.eop & (counter.value == header_length//(dw//8)-2)),
- source.data.eq(header_reg[dw:2*dw]),
- If(source.stb & source.ack,
- shift.eq(1),
- counter.ce.eq(1),
- If(counter.value == header_length//(dw//8)-2,
- NextState("COPY")
+ if header_words != 1:
+ fsm.act("SEND_HEADER",
+ source.stb.eq(1),
+ source.sop.eq(0),
+ source.eop.eq(sink.eop & (counter.value == header_words-2)),
+ source.data.eq(header_reg[dw:2*dw]),
+ If(source.stb & source.ack,
+ shift.eq(1),
+ counter.ce.eq(1),
+ If(counter.value == header_words-2,
+ NextState("COPY")
+ )
)
)
- )
fsm.act("COPY",
source.stb.eq(sink.stb),
source.sop.eq(0),