Skip to content

Commit 0ab235f

Browse files
committed
trace: Move trace pipeline to Amaranth.
1 parent b3b1199 commit 0ab235f

17 files changed

Lines changed: 1575 additions & 1069 deletions

orbtrace/soc.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from litex.soc.integration.soc_core import SoCCore
77
from litex.soc.integration.soc import SoCRegion
88

9-
from .trace import TraceCore
9+
from .trace.glue import TraceCore
1010
from .trace.usb_handler import TraceUSBHandler
1111

1212
from .power.usb_handler import PowerUSBHandler
@@ -408,7 +408,7 @@ def add_cmsis_dap(self, with_v1 = True, with_v2 = True):
408408

409409
def add_trace(self):
410410
# Trace core.
411-
self.submodules.trace = TraceCore(self.platform)
411+
self.submodules.trace = TraceCore(self.platform, self.wrapper)
412412

413413
# LEDs
414414
if hasattr(self, 'led_trace'):

orbtrace/stream.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
from amaranth import *
2+
from amaranth.lib import stream, data, wiring, fifo
3+
4+
class Packet(data.StructLayout):
5+
def __init__(self, element_shape = 8, *, has_first = False, has_last = False):
6+
assert has_first or has_last
7+
layout = {'data': element_shape}
8+
if has_first:
9+
layout['first'] = 1
10+
if has_last:
11+
layout['last'] = 1
12+
super().__init__(layout)
13+
14+
self.has_first = has_first
15+
self.has_last = has_last
16+
17+
class SyncFIFOBuffered(wiring.Component):
18+
def __init__(self, shape, depth):
19+
super().__init__({
20+
'input': wiring.In(stream.Signature(shape)),
21+
'output': wiring.Out(stream.Signature(shape)),
22+
})
23+
self.width = Shape.cast(shape).width
24+
self.depth = depth
25+
26+
def elaborate(self, platform):
27+
m = Module()
28+
m.submodules.fifo = _fifo = fifo.SyncFIFOBuffered(width = self.width, depth = self.depth)
29+
30+
m.d.comb += [
31+
# Input
32+
self.input.ready.eq(_fifo.w_rdy),
33+
_fifo.w_en.eq(self.input.valid),
34+
_fifo.w_data.eq(self.input.payload),
35+
36+
# Output
37+
self.output.valid.eq(_fifo.r_rdy),
38+
self.output.payload.eq(_fifo.r_data),
39+
_fifo.r_en.eq(self.output.ready),
40+
]
41+
42+
return m
43+
44+
class AsyncFIFOBuffered(wiring.Component):
45+
def __init__(self, shape, depth):
46+
super().__init__({
47+
'input': wiring.In(stream.Signature(shape)),
48+
'output': wiring.Out(stream.Signature(shape)),
49+
})
50+
self.width = Shape.cast(shape).width
51+
self.depth = depth
52+
53+
def elaborate(self, platform):
54+
m = Module()
55+
m.submodules.fifo = _fifo = fifo.AsyncFIFOBuffered(width = self.width, depth = self.depth)
56+
57+
m.d.comb += [
58+
# Input
59+
self.input.ready.eq(_fifo.w_rdy),
60+
_fifo.w_en.eq(self.input.valid),
61+
_fifo.w_data.eq(self.input.payload),
62+
63+
# Output
64+
self.output.valid.eq(_fifo.r_rdy),
65+
self.output.payload.eq(_fifo.r_data),
66+
_fifo.r_en.eq(self.output.ready),
67+
]
68+
69+
return m
70+
71+
class Serializer(wiring.Component):
72+
def __init__(self, shape: data.ArrayLayout):
73+
assert isinstance(shape, data.ArrayLayout)
74+
75+
super().__init__({
76+
'input': wiring.In(stream.Signature(shape)),
77+
'output': wiring.Out(stream.Signature(shape.elem_shape)),
78+
})
79+
80+
self.shape = shape
81+
82+
def elaborate(self, platform):
83+
m = Module()
84+
85+
idx = Signal(range(self.shape.length))
86+
87+
m.d.comb += [
88+
self.input.ready.eq(self.output.ready & (idx == self.shape.length - 1)),
89+
self.output.valid.eq(self.input.valid),
90+
self.output.payload.eq(self.input.payload[idx]),
91+
]
92+
93+
with m.If(self.output.valid & self.output.ready):
94+
m.d.sync += idx.eq(idx + 1)
95+
96+
with m.If(idx == self.shape.length - 1):
97+
m.d.sync += idx.eq(0)
98+
99+
return m

0 commit comments

Comments
 (0)