1
+ from migen import *
2
+
3
+ from litex .soc .interconnect .stream import Endpoint , Pipeline , CombinatorialActor , Converter
4
+
5
+ class Rearrange (CombinatorialActor ):
6
+ def __init__ (self ):
7
+ self .sink = sink = Endpoint ([('data' , 128 )])
8
+ self .source = source = Endpoint ([('data' , 135 )])
9
+
10
+ self .comb += source .data .eq (Cat (
11
+ sink .data [120 ], sink .data [1 :8 ], sink .data [0 ],
12
+ sink .data [8 :16 ], C (0 , 1 ),
13
+ sink .data [121 ], sink .data [17 :24 ], sink .data [16 ],
14
+ sink .data [24 :32 ], C (0 , 1 ),
15
+ sink .data [122 ], sink .data [33 :40 ], sink .data [32 ],
16
+ sink .data [40 :48 ], C (0 , 1 ),
17
+ sink .data [123 ], sink .data [49 :56 ], sink .data [48 ],
18
+ sink .data [56 :64 ], C (0 , 1 ),
19
+ sink .data [124 ], sink .data [65 :72 ], sink .data [64 ],
20
+ sink .data [72 :80 ], C (0 , 1 ),
21
+ sink .data [125 ], sink .data [81 :88 ], sink .data [80 ],
22
+ sink .data [88 :96 ], C (0 , 1 ),
23
+ sink .data [126 ], sink .data [97 :104 ], sink .data [96 ],
24
+ sink .data [104 :112 ], C (0 , 1 ),
25
+ sink .data [127 ], sink .data [113 :120 ], sink .data [112 ],
26
+ ))
27
+
28
+ super ().__init__ ()
29
+
30
+ class TrackStream (Module ):
31
+ def __init__ (self ):
32
+ self .sink = sink = Endpoint ([('data' , 9 )])
33
+ self .source = source = Endpoint ([('channel' , 7 ), ('data' , 8 )])
34
+
35
+ channel = Signal (7 )
36
+ next_channel = Signal (7 )
37
+ next_channel_valid = Signal ()
38
+
39
+ self .sync += If (sink .valid & sink .ready & next_channel_valid ,
40
+ channel .eq (next_channel ),
41
+ next_channel_valid .eq (0 ),
42
+ )
43
+
44
+ self .sync += If (sink .valid & sink .data [8 ],
45
+ If (sink .data [0 ],
46
+ next_channel .eq (sink .data [1 :8 ]),
47
+ next_channel_valid .eq (1 ),
48
+ ).Else (
49
+ channel .eq (sink .data [1 :8 ]),
50
+ ),
51
+ )
52
+
53
+ self .comb += [
54
+ source .channel .eq (channel ),
55
+ source .data .eq (sink .data [0 :8 ]),
56
+ If (sink .data [8 ],
57
+ sink .ready .eq (1 ),
58
+ ).Else (
59
+ sink .ready .eq (source .ready ),
60
+ source .valid .eq (sink .valid ),
61
+ ),
62
+ ]
63
+
64
+ class Demux (Module ):
65
+ def __init__ (self ):
66
+ self .sink = sink = Endpoint ([('channel' , 7 ), ('data' , 8 )])
67
+ self .source_itm = source_itm = Endpoint ([('data' , 8 )])
68
+ self .source_etm = source_etm = Endpoint ([('data' , 8 )])
69
+
70
+ self .comb += Case (sink .channel , {
71
+ 1 : sink .connect (source_itm , omit = {'channel' }),
72
+ 2 : sink .connect (source_etm , omit = {'channel' }),
73
+ 'default' : sink .ready .eq (1 ),
74
+ })
75
+
76
+ class StripChannelZero (Module ):
77
+ def __init__ (self ):
78
+ self .sink = sink = Endpoint ([('channel' , 7 ), ('data' , 8 )])
79
+ self .source = source = Endpoint ([('channel' , 7 ), ('data' , 8 )])
80
+
81
+ self .comb += [
82
+ sink .connect (source ),
83
+
84
+ If (sink .channel == 0 ,
85
+ sink .ready .eq (1 ),
86
+ source .valid .eq (0 ),
87
+ ),
88
+ ]
89
+
90
+ class Packetizer (Module ):
91
+ def __init__ (self ):
92
+ self .sink = sink = Endpoint ([('channel' , 7 ), ('data' , 8 )])
93
+ self .source = source = Endpoint ([('data' , 8 )])
94
+
95
+ channel = Signal (7 )
96
+
97
+ self .submodules .fsm = fsm = FSM ()
98
+
99
+ fsm .act ('DATA' ,
100
+ source .data .eq (sink .data ),
101
+ source .valid .eq (sink .valid & (sink .channel == channel )),
102
+ sink .ready .eq (source .ready & (sink .channel == channel )),
103
+
104
+ If (sink .valid & (sink .channel != channel ),
105
+ NextState ('HEADER' ),
106
+ NextValue (channel , sink .channel ),
107
+ ),
108
+ )
109
+
110
+ fsm .act ('HEADER' ,
111
+ source .data .eq (channel ),
112
+ source .first .eq (1 ),
113
+ source .valid .eq (1 ),
114
+
115
+ If (source .ready ,
116
+ NextState ('DATA' ),
117
+ ),
118
+ )
119
+
120
+ class LastFromFirst (Module ):
121
+ def __init__ (self ):
122
+ self .sink = sink = Endpoint ([('data' , 8 )])
123
+ self .source = source = Endpoint ([('data' , 8 )])
124
+
125
+ data = Signal (8 )
126
+ first = Signal ()
127
+ valid = Signal ()
128
+
129
+ self .comb += [
130
+ sink .ready .eq (~ valid | (source .ready & source .valid )),
131
+
132
+ source .data .eq (data ),
133
+ source .first .eq (first ),
134
+ source .last .eq (sink .first ),
135
+ source .valid .eq (valid & sink .valid ),
136
+ ]
137
+
138
+ self .sync += [
139
+ If (sink .ready & sink .valid ,
140
+ data .eq (sink .data ),
141
+ first .eq (sink .first ),
142
+ valid .eq (1 ),
143
+ ),
144
+ ]
145
+
146
+ class TPIUDemux (Module ):
147
+ def __init__ (self ):
148
+ self .sink = sink = Endpoint ([('data' , 128 )])
149
+ self .source = source = Endpoint ([('data' , 8 )])
150
+
151
+ self .submodules .rearrange = Rearrange ()
152
+ self .submodules .converter = Converter (135 , 9 )
153
+ self .submodules .track_stream = TrackStream ()
154
+ self .submodules .demux = Demux ()
155
+ self .submodules .strip_channel_zero = StripChannelZero ()
156
+ self .submodules .packetizer = Packetizer ()
157
+ self .submodules .last_from_first = LastFromFirst ()
158
+
159
+ self .submodules .pipeline = Pipeline (
160
+ sink ,
161
+ self .rearrange ,
162
+ self .converter ,
163
+ self .track_stream ,
164
+ #self.demux,
165
+ self .strip_channel_zero ,
166
+ self .packetizer ,
167
+ self .last_from_first ,
168
+ source ,
169
+ )
170
+
171
+ #self.comb += self.demux.source_etm.connect(source)
172
+ #self.comb += self.demux.source_itm.ready.eq(1)
0 commit comments