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()
147 self
.reads
= self
.get_reads()
151 def set_writes(self
, writes
):
152 self
.wcount
= len(writes
.writes
)
157 def set_reads(self
, reads
):
158 self
.rcount
= len(reads
.reads
)
166 if self
.writes
is not None:
167 self
.set_writes(self
.writes
)
168 if self
.reads
is not None:
169 self
.set_reads(self
.reads
)
171 for k
, v
in sorted(etherbone_record_header
.items()):
172 value
= merge_bytes(split_bytes(getattr(self
, k
), math
.ceil(v
.width
/8)), "little")
173 header
+= (value
<< v
.offset
+(v
.byte
*8))
174 for d
in split_bytes(header
, etherbone_record_header_len
):
178 def __repr__(self
, n
=0):
179 r
= "Record {}\n".format(n
)
183 r
+= "{:02x}".format(d
)
185 for k
in sorted(etherbone_record_header
.keys()):
186 r
+= k
+ " : 0x{:0x}\n".format(getattr(self
,k
))
188 r
+= self
.writes
.__repr
__()
190 r
+= self
.reads
.__repr
__()
193 class EtherbonePacket(Packet
):
194 def __init__(self
, init
=[]):
195 Packet
.__init
__(self
, init
)
196 self
.encoded
= init
!= []
199 self
.magic
= etherbone_magic
200 self
.version
= etherbone_version
201 self
.addr_size
= 32//8
202 self
.port_size
= 32//8
207 def get_records(self
):
211 while len(payload
) != 0:
212 record
= EtherboneRecord(payload
)
214 records
.append(copy
.deepcopy(record
))
222 for byte
in self
[:etherbone_packet_header_len
]:
223 header
.append(self
.pop(0))
224 for k
, v
in sorted(etherbone_packet_header
.items()):
225 setattr(self
, k
, get_field_data(v
, header
))
226 self
.records
= self
.get_records()
229 def set_records(self
, records
):
230 for record
in records
:
238 self
.set_records(self
.records
)
240 for k
, v
in sorted(etherbone_packet_header
.items()):
241 value
= merge_bytes(split_bytes(getattr(self
, k
), math
.ceil(v
.width
/8)), "little")
242 header
+= (value
<< v
.offset
+(v
.byte
*8))
243 for d
in split_bytes(header
, etherbone_packet_header_len
):
252 r
+= "{:02x}".format(d
)
254 for k
in sorted(etherbone_packet_header
.keys()):
255 r
+= k
+ " : 0x{:0x}\n".format(getattr(self
,k
))
256 for i
, record
in enumerate(self
.records
):
257 r
+= record
.__repr
__(i
)
260 class Etherbone(Module
):
261 def __init__(self
, udp
, debug
=False):
265 self
.tx_packet
= EtherbonePacket()
266 self
.rx_packet
= EtherbonePacket()
268 udp
.set_etherbone_callback(self
.callback
)
270 def send(self
, packet
):
273 print_etherbone(">>>>>>>>")
274 print_etherbone(packet
)
275 udp_packet
= udp
.UDPPacket(packet
)
276 udp_packet
.src_port
= 0x1234 # XXX
277 udp_packet
.dst_port
= 20000 # XXX
278 udp_packet
.length
= len(packet
)
279 udp_packet
.checksum
= 0
280 self
.udp
.send(udp_packet
)
282 def callback(self
, packet
):
283 packet
= EtherbonePacket(packet
)
286 print_etherbone("<<<<<<<<")
287 print_etherbone(packet
)
290 def process(self
, packet
):
293 if __name__
== "__main__":
295 writes
= EtherboneWrites(base_addr
=0x1000)
297 writes
.add(EtherboneWrite(i
))
298 reads
= EtherboneReads(base_ret_addr
=0x2000)
300 reads
.add(EtherboneRead(i
))
303 record
= EtherboneRecord()
304 record
.writes
= writes
312 record
.byte_enable
= 0
317 packet
= EtherbonePacket()
318 packet
.records
= [copy
.deepcopy(record
) for i
in range(8)]
326 # Send packet over UDP to check against Wireshark dissector
328 sock
= socket
.socket(socket
.AF_INET
, socket
.SOCK_DGRAM
)
329 sock
.sendto(bytes(packet
), ("192.168.1.1", 20000))
331 packet
= EtherbonePacket(packet
)