Skip to content

Commit 86f0f12

Browse files
author
whitequark
committed
lib.cdc: avoid modifying synchronizers in their elaborate() method.
1 parent 51f03bb commit 86f0f12

File tree

3 files changed

+34
-22
lines changed

3 files changed

+34
-22
lines changed

nmigen/lib/cdc.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,22 @@ def __init__(self, i, o, *, o_domain="sync", stages=2, reset=0, reset_less=True)
5757
self.i = i
5858
self.o = o
5959

60-
self._o_domain = o_domain
61-
self._stages = [Signal(self.i.shape(), name="stage{}".format(index),
62-
reset=reset, reset_less=reset_less)
63-
for index in range(stages)]
60+
self._reset = reset
61+
self._reset_less = reset_less
62+
self._o_domain = o_domain
63+
self._stages = stages
6464

6565
def elaborate(self, platform):
6666
if hasattr(platform, "get_ff_sync"):
6767
return platform.get_ff_sync(self)
6868

6969
m = Module()
70-
for i, o in zip((self.i, *self._stages), self._stages):
70+
flops = [Signal(self.i.shape(), name="stage{}".format(index),
71+
reset=self._reset, reset_less=self._reset_less)
72+
for index in range(self._stages)]
73+
for i, o in zip((self.i, *flops), flops):
7174
m.d[self._o_domain] += o.eq(i)
72-
m.d.comb += self.o.eq(self._stages[-1])
75+
m.d.comb += self.o.eq(flops[-1])
7376
return m
7477

7578

@@ -82,20 +85,21 @@ def __init__(self, arst, *, domain="sync", stages=2):
8285
self.arst = arst
8386

8487
self._domain = domain
85-
self._stages = [Signal(1, name="stage{}".format(i), reset=1)
86-
for i in range(stages)]
88+
self._stages = stages
8789

8890
def elaborate(self, platform):
8991
if hasattr(platform, "get_reset_sync"):
9092
return platform.get_reset_sync(self)
9193

9294
m = Module()
9395
m.domains += ClockDomain("reset_sync", async_reset=True, local=True)
94-
for i, o in zip((0, *self._stages), self._stages):
96+
flops = [Signal(1, name="stage{}".format(index), reset=1)
97+
for index in range(self._stages)]
98+
for i, o in zip((0, *flops), flops):
9599
m.d.reset_sync += o.eq(i)
96100
m.d.comb += [
97101
ClockSignal("reset_sync").eq(ClockSignal(self._domain)),
98102
ResetSignal("reset_sync").eq(self.arst),
99-
ResetSignal(self._domain).eq(self._stages[-1])
103+
ResetSignal(self._domain).eq(flops[-1])
100104
]
101105
return m

nmigen/vendor/xilinx_7series.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -363,8 +363,11 @@ def get_diff_input_output(self, pin, p_port, n_port, attrs, invert):
363363

364364
def get_ff_sync(self, ff_sync):
365365
m = Module()
366-
for i, o in zip((ff_sync.i, *ff_sync._stages), ff_sync._stages):
367-
o.attrs["ASYNC_REG"] = "TRUE"
366+
flops = [Signal(ff_sync.i.shape(), name="stage{}".format(index),
367+
reset=ff_sync._reset, reset_less=ff_sync._reset_less,
368+
attrs={"ASYNC_REG": "TRUE"})
369+
for index in range(ff_sync._stages)]
370+
for i, o in zip((ff_sync.i, *flops), flops):
368371
m.d[ff_sync._o_domain] += o.eq(i)
369-
m.d.comb += ff_sync.o.eq(ff_sync._stages[-1])
372+
m.d.comb += ff_sync.o.eq(flops[-1])
370373
return m

nmigen/vendor/xilinx_spartan_3_6.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -413,22 +413,27 @@ def get_diff_input_output(self, pin, p_port, n_port, attrs, invert):
413413

414414
def get_ff_sync(self, ff_sync):
415415
m = Module()
416-
for i, o in zip((ff_sync.i, *ff_sync._stages), ff_sync._stages):
417-
o.attrs["ASYNC_REG"] = "TRUE"
416+
flops = [Signal(ff_sync.i.shape(), name="stage{}".format(index),
417+
reset=ff_sync._reset, reset_less=ff_sync._reset_less,
418+
attrs={"ASYNC_REG": "TRUE"})
419+
for index in range(ff_sync._stages)]
420+
for i, o in zip((ff_sync.i, *flops), flops):
418421
m.d[ff_sync._o_domain] += o.eq(i)
419-
m.d.comb += ff_sync.o.eq(multireg._stages[-1])
422+
m.d.comb += ff_sync.o.eq(flops[-1])
420423
return m
421424

422-
def get_reset_sync(self, resetsync):
425+
def get_reset_sync(self, reset_sync):
423426
m = Module()
424427
m.domains += ClockDomain("reset_sync", async_reset=True, local=True)
425-
for i, o in zip((0, *resetsync._stages), resetsync._stages):
426-
o.attrs["ASYNC_REG"] = "TRUE"
428+
flops = [Signal(1, name="stage{}".format(index), reset=1,
429+
attrs={"ASYNC_REG": "TRUE"})
430+
for index in range(reset_sync._stages)]
431+
for i, o in zip((0, *flops), flops):
427432
m.d.reset_sync += o.eq(i)
428433
m.d.comb += [
429-
ClockSignal("reset_sync").eq(ClockSignal(resetsync._domain)),
430-
ResetSignal("reset_sync").eq(resetsync.arst),
431-
ResetSignal(resetsync._domain).eq(resetsync._stages[-1])
434+
ClockSignal("reset_sync").eq(ClockSignal(reset_sync._domain)),
435+
ResetSignal("reset_sync").eq(reset_sync.arst),
436+
ResetSignal(reset_sync._domain).eq(flops[-1])
432437
]
433438
return m
434439

0 commit comments

Comments
 (0)