Skip to content

Commit ba52bef

Browse files
committed
interface/stream: option to change the converter order
1 parent eb35139 commit ba52bef

File tree

1 file changed

+32
-12
lines changed

1 file changed

+32
-12
lines changed

lambdalib/interface/stream.py

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -353,41 +353,61 @@ def elaborate(self, platform):
353353

354354
class Converter(Elaboratable):
355355
def __init__(self, nbits_from, nbits_to, cd_from="sync", cd_to="sync",
356-
reverse=False, buffered=True):
356+
reverse=False, buffered=True,
357+
put_width_converter_first=True):
357358
self.nbits_from = nbits_from
358359
self.nbits_to = nbits_to
359360
self.cd_from = cd_from
360361
self.cd_to = cd_to
361362
self.reverse = reverse
362363
self.buffered = buffered
364+
self.put_width_converter_first = put_width_converter_first
363365

364366
self.sink = Endpoint([("data", nbits_from)])
365367
self.source = Endpoint([("data", nbits_to)])
366368

367-
def elaborate(self, platform):
368-
sin = self.sink
369-
370-
m = Module()
371-
369+
def put_width_converter(self, m, s):
372370
# Need width converter ?
373371
if self.nbits_from != self.nbits_to:
374372
m.submodules.cvt = cvt = DomainRenamer(self.cd_from)(
375373
_Converter(self.nbits_from, self.nbits_to, reverse=self.reverse)
376374
)
377375

378-
m.d.comb += sin.connect(cvt.sink)
379-
sin = cvt.source
376+
m.d.comb += s.connect(cvt.sink)
377+
return cvt.source
378+
379+
return s
380380

381+
def put_cross_domain(self, m, s):
381382
# Need cross domain clocking ?
382383
if self.cd_from != self.cd_to:
383384
m.submodules.asc = asc = AsyncFIFO(
384-
sin.description, 8, buffered=self.buffered,
385+
s.description, 8, buffered=self.buffered,
385386
w_domain=self.cd_from, r_domain=self.cd_to,
386387
)
387388

388-
m.d.comb += sin.connect(asc.sink)
389-
sin = asc.source
389+
m.d.comb += s.connect(asc.sink)
390+
return asc.source
390391

391-
m.d.comb += sin.connect(self.source)
392+
return s
393+
394+
def elaborate(self, platform):
395+
m = Module()
396+
397+
# Depending on the design we give the choice to change the
398+
# conversion order. This has an importance:
399+
# - Cross domain FIFO is gate costly, we might want to put
400+
# it on the smallest width side to save gates.
401+
# - But clock frequencies are important too:
402+
# we might want to perform the width conversion in the fastest
403+
# clock domain to preserve the overall data throughput.
404+
s = self.sink
405+
if self.put_width_converter_first:
406+
s = self.put_width_converter(m, s)
407+
s = self.put_cross_domain(m, s)
408+
else:
409+
s = self.put_cross_domain(m, s)
410+
s = self.put_width_converter(m, s)
411+
m.d.comb += s.connect(self.source)
392412

393413
return m

0 commit comments

Comments
 (0)