Skip to content

Commit

Permalink
lib.cdc: avoid interior clock domains in ResetSynchronizer.
Browse files Browse the repository at this point in the history
Such clock domains will "leak" into the enclosing scope, which is
generally undesirable. Also, this is instructive for a platform
overriding the behavior, since it provides guidance on how to
correctly instantiate platform-specific flops.

I've considered also doing this for MultiReg(), but it is very
challenging in presence of non-reset-less CDC FFs, since Yosys'
$dffsr primitive has separate set and clear inputs, and reshuffling
the reset value for those results in quite a bit of additional logic.

(That said, it might have to be done anyway, precisely because
letting Yosys generate this additional logic might prove too much
for the toolchain to cope with, and again, platform-independent
code should provide guidance to platform-specific code.)
  • Loading branch information
whitequark committed Jun 28, 2019
1 parent 21379dd commit 779f3ee
Showing 1 changed file with 12 additions and 8 deletions.
20 changes: 12 additions & 8 deletions nmigen/lib/cdc.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,16 @@ def elaborate(self, platform):
return platform.get_reset_sync(self)

m = Module()
m.domains += ClockDomain("_reset_sync", async_reset=True)
for i, o in zip((0, *self._regs), self._regs):
m.d._reset_sync += o.eq(i)
m.d.comb += [
ClockSignal("_reset_sync").eq(ClockSignal(self.domain)),
ResetSignal("_reset_sync").eq(self.arst),
ResetSignal(self.domain).eq(self._regs[-1])
]
for i, o in zip((Const(0, 1), *self._regs), self._regs):
m.submodules += Instance("$adff",
p_CLK_POLARITY=1,
p_ARST_POLARITY=1,
p_ARST_VALUE=Const(1, 1),
p_WIDTH=1,
i_CLK=ClockSignal(self.domain),
i_ARST=self.arst,
i_D=i,
o_Q=o
)
m.d.comb += ResetSignal(self.domain).eq(self._regs[-1])
return m

0 comments on commit 779f3ee

Please sign in to comment.