Skip to content

Commit 70353b8

Browse files
committed
wip: Decode TPIU frames, reframe the payload with a simple header and feed to COBS encoder.
1 parent 0d6cbda commit 70353b8

File tree

2 files changed

+179
-6
lines changed

2 files changed

+179
-6
lines changed

orbtrace/trace/__init__.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from .swo import ManchesterDecoder, PulseLengthCapture, BitsToBytes, NRZDecoder, UARTDecoder
88

9-
from . import cobs
9+
from . import cobs, tpiu
1010

1111
class TracePHY(Module):
1212
def __init__(self, pads):
@@ -308,15 +308,16 @@ def __init__(self, platform):
308308
phy := ClockDomainsRenamer('trace')(TracePHY(trace_pads)),
309309
ClockDomainsRenamer({'write': 'trace', 'read': 'sys'})(AsyncFIFO([('data', 128)], 4)),
310310
ByteSwap(16),
311-
injector := Injector(),
312-
pv := PipeValid([('data', 128)]),
313-
Converter(128, 8),
311+
#injector := Injector(),
312+
#pv := PipeValid([('data', 128)]),
313+
#Converter(128, 8),
314+
tpiu.TPIUDemux(),
314315
cobs.COBSEncoder(),
315316
cobs.DelimiterAppender(),
316317
cobs.SuperFramer(7500000, 65536),
317318
]
318319

319-
pv.comb += pv.source.last.eq(1)
320+
#pv.comb += pv.source.last.eq(1)
320321

321322
trace_stream = Endpoint([('data', 8)])
322323

@@ -333,7 +334,7 @@ def __init__(self, platform):
333334
self.comb += [
334335
keepalive.total_frames.eq(monitor.total),
335336
keepalive.lost_frames.eq(monitor.lost),
336-
keepalive.source.connect(injector.sink_inject),
337+
#keepalive.source.connect(injector.sink_inject),
337338
]
338339

339340
self.submodules += monitor, keepalive

orbtrace/trace/tpiu.py

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
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

Comments
 (0)