-
Notifications
You must be signed in to change notification settings - Fork 154
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Clash.Clocks
lock signal
#2417
Conversation
The extra myPll ::
(KnownDomain domIn, KnownDomain domOut) =>
Clock domIn ->
Reset domIn ->
(Clock domOut, Signal pllLock Bool)
myPll = altpll (SSymbol @"mypll") and now needs to add [edit] |
The lock signal is now `False` for the time that the input reset signal is asserted, and `True` when the input reset signal is not asserted. Before this commit, the lock signal output was defined in terms of the reset input as follows: ``` rstIn :: Reset domIn lockOut :: Signal domOut Bool lockOut = unsafeCoerce rstIn ``` This is incorrect in three ways: * You can't coerce a `Reset` into a `Signal`, it segfaults. * The time base is wrong: one input sample becomes one output sample even when the output clock has a different period than the input clock. * There is no handling of `ResetPolarity`; the simulation model is that lock is deasserted when reset is asserted.
ffb4304
to
2a028b3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the examples now also require an type annotation on the pllLocked
signal to type check:
clash-compiler/clash-prelude/src/Clash/Intel/ClockGen.hs
Lines 144 to 145 in 2a028b3
-- (clk100 :: 'Clock' Dom100MHz, pllLocked) = | |
-- 'alteraPll' ('SSymbol' \@\"alterapll50to100\") clk50 rst50 |
clash-compiler/clash-prelude/src/Clash/Intel/ClockGen.hs
Lines 154 to 155 in 2a028b3
-- (clk100 :: 'Clock' Dom100MHz, clk150 :: 'Clock' Dom150MHz, pllLocked) = | |
-- 'alteraPll' ('SSymbol' \@\"alterapllmulti\") clk50 rst50 |
This next one already has all the type annotations, but is missing the =
between the pattern and the alteraPll
. Maybe you can fix that while you're in there.
clash-compiler/clash-prelude/src/Clash/Intel/ClockGen.hs
Lines 178 to 180 in 2a028b3
-- (clk :: 'Clock' 'Clash.Signal.System', pllStable :: 'Signal' 'Clash.Signal.System' 'Bool') | |
-- 'alteraPll' ('SSymbol' \@\"alterapll50to100\") clkInp | |
-- ('Clash.Signal.unsafeFromLowPolarity' rstInp) |
And the Xilinx prims clockWizard
and clockWizardDifferential
don't have the same crashing issues, but do a similar unsafeCoerce
between domains with (potentially) different periods.
clash-compiler/clash-prelude/src/Clash/Xilinx/ClockGen.hs
Lines 55 to 56 in 2a028b3
clockWizard !_ clk@(Clock _ Nothing) rst = | |
(unsafeCoerce clk, unsafeCoerce (toEnable (unsafeToHighPolarity rst))) |
We've talked about the points Leon raises. The documentation now is not incorrect (modulo the missing |
The lock signal is now `False` for the time that the input reset signal is asserted, and `True` when the input reset signal is not asserted. Before this commit, the lock signal output was defined in terms of the reset input as follows: ``` rstIn :: Reset domIn lockOut :: Signal pllOut Bool lockOut = unsafeCoerce rstIn ``` This is incorrect in three ways: * You can't coerce a `Reset` into a `Signal`, it segfaults. * The timebase is wrong: one input sample becomes one output sample even when the output clock has a different period than the input clock. * There is no handling of `ResetPolarity`; the simulation model is that lock is deasserted when reset is asserted. (cherry picked from commit c60353e) # Conflicts: # clash-prelude/src/Clash/Clocks/Deriving.hs
The lock signal is now `False` for the time that the input reset signal is asserted, and `True` when the input reset signal is not asserted. Before this commit, the lock signal output was defined in terms of the reset input as follows: ``` rstIn :: Reset domIn lockOut :: Signal pllOut Bool lockOut = unsafeCoerce rstIn ``` This is incorrect in three ways: * You can't coerce a `Reset` into a `Signal`, it segfaults. * The timebase is wrong: one input sample becomes one output sample even when the output clock has a different period than the input clock. * There is no handling of `ResetPolarity`; the simulation model is that lock is deasserted when reset is asserted. (cherry picked from commit c60353e)
The lock signal is now `False` for the time that the input reset signal is asserted, and `True` when the input reset signal is not asserted. Before this commit, the lock signal output was defined in terms of the reset input as follows: ``` rstIn :: Reset domIn lockOut :: Signal pllOut Bool lockOut = unsafeCoerce rstIn ``` This is incorrect in three ways: * You can't coerce a `Reset` into a `Signal`, it segfaults. * The timebase is wrong: one input sample becomes one output sample even when the output clock has a different period than the input clock. * There is no handling of `ResetPolarity`; the simulation model is that lock is deasserted when reset is asserted. (cherry picked from commit c60353e) Co-authored-by: Peter Lebbing <peter@digitalbrains.com>
PR #2417 caused a bug in the generation of the `qsys` file: it generated a spurious extra output clock which was completely unused otherwise.
The way we tried to generate the lock signal in
Clash.Clocks
was very wrong. For instance, aClash.Intel.ClockGen.alteraPll
with two clock outputs would boil down to:unsafeCoerce rst
is wrong in three ways:Reset
into aSignal
, it segfaults.ResetPolarity
. The simulation model is that lock is deasserted when reset is asserted, but this was not effected.This PR changes the implementation to:
Note that we needed a
KnownDomain pllLock
as well.Still TODO: