3 from liteeth
.common
import *
4 from liteeth
.test
.common
import *
6 from liteeth
.test
.model
import udp
8 def print_etherbone(s
):
9 print_with_prefix(s
, "[ETHERBONE]")
13 def __init__(self
, data
):
17 return "WR32 0x{:08x}".format(self
.data
)
20 def __init__(self
, addr
):
24 return "RD32 @ 0x{:08x}".format(self
.addr
)
26 class EtherboneWrites(Packet
):
27 def __init__(self
, init
=[], base_addr
=0):
28 Packet
.__init
__(self
, init
)
29 self
.base_addr
= base_addr
31 self
.encoded
= init
!= []
34 self
.writes
.append(write
)
39 for byte
in split_bytes(self
.base_addr
, 4):
41 for write
in self
.writes
:
42 for byte
in split_bytes(write
.data
, 4):
51 base_addr
.append(self
.pop(0))
52 self
.base_addr
= merge_bytes(base_addr
)
57 write
.append(self
.pop(0))
58 self
.writes
.append(EtherboneWrite(merge_bytes(write
)))
64 r
+= "BaseAddr @ 0x{:08x}\n".format(self
.base_addr
)
65 for write
in self
.writes
:
66 r
+= write
.__repr
__() + "\n"
69 class EtherboneReads(Packet
):
70 def __init__(self
, init
=[], base_ret_addr
=0):
71 Packet
.__init
__(self
, init
)
72 self
.base_ret_addr
= base_ret_addr
74 self
.encoded
= init
!= []
77 self
.reads
.append(read
)
82 for byte
in split_bytes(self
.base_ret_addr
, 4):
84 for read
in self
.reads
:
85 for byte
in split_bytes(read
.addr
, 4):
94 base_ret_addr
.append(self
.pop(0))
95 self
.base_ret_addr
= merge_bytes(base_ret_addr
)
100 read
.append(self
.pop(0))
101 self
.reads
.append(EtherboneRead(merge_bytes(read
)))
107 r
+= "BaseRetAddr @ 0x{:08x}\n".format(self
.base_ret_addr
)
108 for read
in self
.reads
:
109 r
+= read
.__repr
__() + "\n"
112 class EtherboneRecord(Packet
):
113 def __init__(self
, init
=[]):
114 Packet
.__init
__(self
, init
)
117 self
.encoded
= init
!= []
119 def get_writes(self
):
124 for i
in range((self
.wcount
+1)*4):
125 writes
.append(self
.pop(0))
126 return EtherboneWrites(writes
)
133 for i
in range((self
.rcount
+1)*4):
134 reads
.append(self
.pop(0))
135 return EtherboneReads(reads
)
141 for byte
in self
[:etherbone_record_header_len
]:
142 header
.append(self
.pop(0))
143 for k
, v
in sorted(etherbone_record_header
.items()):
144 setattr(self
, k
, get_field_data(v
, header
))
145 self
.writes
= self
.get_writes()
146 if self
.writes
is not None:
148 self
.reads
= self
.get_reads()
149 if self
.reads
is not None:
153 def set_writes(self
, writes
):
154 self
.wcount
= len(writes
.writes
)
159 def set_reads(self
, reads
):
160 self
.rcount
= len(reads
.reads
)
168 if self
.writes
is not None:
169 self
.set_writes(self
.writes
)
170 if self
.reads
is not None:
171 self
.set_reads(self
.reads
)
173 for k
, v
in sorted(etherbone_record_header
.items()):
174 value
= merge_bytes(split_bytes(getattr(self
, k
), math
.ceil(v
.width
/8)), "little")
175 header
+= (value
<< v
.offset
+(v
.byte
*8))
176 for d
in split_bytes(header
, etherbone_record_header_len
):
180 def __repr__(self
, n
=0):
181 r
= "Record {}\n".format(n
)
185 r
+= "{:02x}".format(d
)
187 for k
in sorted(etherbone_record_header
.keys()):
188 r
+= k
+ " : 0x{:0x}\n".format(getattr(self
,k
))
190 r
+= self
.writes
.__repr
__()
192 r
+= self
.reads
.__repr
__()
195 class EtherbonePacket(Packet
):
196 def __init__(self
, init
=[]):
197 Packet
.__init
__(self
, init
)
198 self
.encoded
= init
!= []
201 self
.magic
= etherbone_magic
202 self
.version
= etherbone_version
203 self
.addr_size
= 32//8
204 self
.port_size
= 32//8
209 def get_records(self
):
213 while len(payload
) != 0:
214 record
= EtherboneRecord(payload
)
216 records
.append(copy
.deepcopy(record
))
224 for byte
in self
[:etherbone_packet_header_len
]:
225 header
.append(self
.pop(0))
226 for k
, v
in sorted(etherbone_packet_header
.items()):
227 setattr(self
, k
, get_field_data(v
, header
))
228 self
.records
= self
.get_records()
231 def set_records(self
, records
):
232 for record
in records
:
240 self
.set_records(self
.records
)
242 for k
, v
in sorted(etherbone_packet_header
.items()):
243 value
= merge_bytes(split_bytes(getattr(self
, k
), math
.ceil(v
.width
/8)), "little")
244 header
+= (value
<< v
.offset
+(v
.byte
*8))
245 for d
in split_bytes(header
, etherbone_packet_header_len
):
254 r
+= "{:02x}".format(d
)
256 for k
in sorted(etherbone_packet_header
.keys()):
257 r
+= k
+ " : 0x{:0x}\n".format(getattr(self
,k
))
258 for i
, record
in enumerate(self
.records
):
259 r
+= record
.__repr
__(i
)
262 class Etherbone(Module
):
263 def __init__(self
, udp
, debug
=False):
267 self
.tx_packet
= EtherbonePacket()
268 self
.rx_packet
= EtherbonePacket()
270 udp
.set_etherbone_callback(self
.callback
)
272 def send(self
, packet
):
275 print_etherbone(">>>>>>>>")
276 print_etherbone(packet
)
277 udp_packet
= udp
.UDPPacket(packet
)
278 udp_packet
.src_port
= 0x1234 # XXX
279 udp_packet
.dst_port
= 20000 # XXX
280 udp_packet
.length
= len(packet
)
281 udp_packet
.checksum
= 0
282 self
.udp
.send(udp_packet
)
284 def callback(self
, packet
):
285 packet
= EtherbonePacket(packet
)
288 print_etherbone("<<<<<<<<")
289 print_etherbone(packet
)
292 def process(self
, packet
):
295 if __name__
== "__main__":
297 writes
= EtherboneWrites(base_addr
=0x1000)
299 writes
.add(EtherboneWrite(i
))
300 reads
= EtherboneReads(base_ret_addr
=0x2000)
302 reads
.add(EtherboneRead(i
))
305 record
= EtherboneRecord()
306 record
.writes
= writes
314 record
.byte_enable
= 0
319 packet
= EtherbonePacket()
320 packet
.records
= [copy
.deepcopy(record
) for i
in range(8)]
328 # Send packet over UDP to check against Wireshark dissector
330 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
331 sock
.sendto(bytes(packet
), ("192.168.1.1", 20000))
333 packet
= EtherbonePacket(packet
)