1 from collections
import OrderedDict
3 from migen
.fhdl
.std
import *
4 from migen
.fhdl
.std
import *
5 from migen
.genlib
.resetsync
import AsyncResetSynchronizer
6 from migen
.genlib
.record
import *
7 from migen
.genlib
.fsm
import FSM
, NextState
8 from migen
.genlib
.misc
import chooser
9 from migen
.flow
.actor
import EndpointDescription
10 from migen
.flow
.actor
import Sink
, Source
11 from migen
.actorlib
.structuring
import Converter
, Pipeline
12 from migen
.actorlib
.fifo
import SyncFIFO
, AsyncFIFO
13 from migen
.bank
.description
import *
16 eth_preamble
= 0xD555555555555555
17 buffer_depth
= 2**log2_int(eth_mtu
, need_pow2
=False)
20 def __init__(self
, byte
, offset
, width
):
27 "destination_mac_address": HField(0, 0, 48),
28 "source_mac_address": HField(6, 0, 48),
29 "ethernet_type": HField(12, 0, 16)
34 "hardware_type": HField( 0, 0, 16),
35 "protocol_type": HField( 2, 0, 16),
36 "hardware_address_length": HField( 4, 0, 8),
37 "protocol_address_length": HField( 5, 0, 8),
38 "operation": HField( 6, 0, 16),
39 "source_mac_address": HField( 8, 0, 48),
40 "source_ip_address": HField(14, 0, 32),
41 "destination_mac_address": HField(18, 0, 48),
42 "destination_ip_address": HField(24, 0, 32)
47 "version": HField(0, 0, 4),
48 "ihl": HField(0, 4, 4),
49 "dscp": HField(1, 0, 6),
50 "ecn": HField(1, 6, 2),
51 "total_length": HField(2, 0, 16),
52 "identification": HField(4, 0, 16),
53 "flags": HField(6, 0, 3),
54 "fragment_offset": HField(6, 3, 13),
55 "time_to_live": HField(8, 0, 8),
56 "protocol": HField(9, 0, 8),
57 "header_checksum": HField(10, 0, 16),
58 "source_ip_address": HField(12, 0, 32),
59 "destination_ip_address": HField(16, 0, 32),
60 "options": HField(20, 0, 32)
64 "source_port": HField( 0, 0, 16),
65 "destination_port": HField( 2, 0, 16),
66 "length": HField( 4, 0, 16),
67 "checksum": HField( 6, 0, 16)
71 def _layout_from_header(header
):
73 for k
, v
in sorted(header
.items()):
74 _layout
.append((k
, v
.width
))
77 def eth_phy_description(dw
):
83 return EndpointDescription(layout
, packetized
=True)
85 def eth_mac_description(dw
):
86 layout
= _layout_from_header(mac_header
) + [
91 return EndpointDescription(layout
, packetized
=True)
93 def eth_arp_description(dw
):
94 layout
= _layout_from_header(arp_header
) + [
98 return EndpointDescription(layout
, packetized
=True)
100 def eth_ipv4_description(dw
):
101 layout
= _layout_from_header(ipv4_header
) + [
105 return EndpointDescription(layout
, packetized
=True)
107 def eth_udp_description(dw
):
108 layout
= _layout_from_header(udp_header
) + [
112 return EndpointDescription(layout
, packetized
=True)
115 @DecorateModule(InsertReset
)
116 @DecorateModule(InsertCE
)
117 class Counter(Module
):
118 def __init__(self
, signal
=None, **kwargs
):
120 self
.value
= Signal(**kwargs
)
123 self
.width
= flen(self
.value
)
124 self
.sync
+= self
.value
.eq(self
.value
+1)
126 @DecorateModule(InsertReset
)
127 @DecorateModule(InsertCE
)
128 class Timeout(Module
):
129 def __init__(self
, length
):
130 self
.reached
= Signal()
132 value
= Signal(max=length
)
133 self
.sync
+= value
.eq(value
+1)
134 self
.comb
+= self
.reached
.eq(value
== length
)
136 class BufferizeEndpoints(ModuleDecorator
):
137 def __init__(self
, submodule
, *args
):
138 ModuleDecorator
.__init
__(self
, submodule
)
140 endpoints
= get_endpoints(submodule
)
143 for name
, endpoint
in endpoints
.items():
144 if name
in args
or len(args
) == 0:
145 if isinstance(endpoint
, Sink
):
146 sinks
.update({name
: endpoint
})
147 elif isinstance(endpoint
, Source
):
148 sources
.update({name
: endpoint
})
150 # add buffer on sinks
151 for name
, sink
in sinks
.items():
152 buf
= Buffer(sink
.description
)
153 self
.submodules
+= buf
154 setattr(self
, name
, buf
.d
)
155 self
.comb
+= Record
.connect(buf
.q
, sink
)
157 # add buffer on sources
158 for name
, source
in sources
.items():
159 buf
= Buffer(source
.description
)
160 self
.submodules
+= buf
161 self
.comb
+= Record
.connect(source
, buf
.d
)
162 setattr(self
, name
, buf
.q
)