Skip to content

Commit de5e00b

Browse files
Document safe PLL's
All the examples in the documentation are adjusted to use safe PLL's. Documents all the changes in this PR
1 parent c3233c7 commit de5e00b

File tree

12 files changed

+738
-268
lines changed

12 files changed

+738
-268
lines changed

changelog/2023-03-01T12_18_28+01_00_xilinx_clocking_wizard

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
11
ADDED: A new clock type `DiffClock` is introduced to signify a differential
22
clock signal that is passed to the design on two ports in antiphase. This is
3-
used by the Xilinx `clockWizardDifferential` IP generator.
4-
5-
CHANGED: Xilinx `clockWizardDifferential` now gets its input clock as a
6-
`DiffClock` type; use `clockToDiffClock` to generate this in your test bench
7-
if needed. Previously, the function received two clock inputs, but this
8-
generated `create_clock` statements in the top-level SDC file for both phases
9-
which is incorrect.
3+
used by the differential Xilinx clock wizards in `Clash.Xilinx.ClockGen`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
REMOVED: The module `Clash.Clocks.Deriving` has been removed.
2+
3+
FIXED: `altpll` and `alteraPll` in `Clash.Intel.ClockGen` now account for the input domain's `ResetPolarity`. Before this fix, the reset was always interpreted as an active-high signal.
4+
5+
CHANGED: The IP core generators in `Clash.Intel.ClockGen` now declare that their input domain needs to have asynchronous resets (`HasAsynchronousReset`), as the functions react asynchronously to their reset input and thus need to be glitch-free. The functions marked `unsafe` do not have this constraint; instead, the function documentation calls attention to the requirement.
6+
7+
INTERNAL NEW: `Clash.Primitives.DSL.declareN`, a companion to `declare` which declares multiple signals in one go.
8+
9+
DEPRECATED: The functions `altpll` and `alteraPll` in `Clash.Intel.ClockGen` have been deprecated because they are unsafe to use while this is not apparent from the name. The `locked` output signal of these functions is an asynchronous signal which needs to be synchronized before it can be used (something the examples did in fact demonstrate). For the common use case, new functions are available, named `altpllSync` and `alteraPllSync`. These functions are safe. For advanced use cases, the old functionality can be obtained through `unsafeAltpll` and `unsafeAlteraPll`.
10+
11+
NEW: `altpllSync` and `alteraPllSync` in `Clash.Intel.ClockGen`. These replace the deprecated functions without the `Sync` suffix. Unlike the old functions, these functions are safe to use and have a reset signal for each output domain that can be used to keep the domain in reset while the clock output stabilizes. All PLL functions now also support multiple clock outputs like the old `alteraPll` did.
12+
13+
CHANGED: The wizards in `Clash.Xilinx.ClockGen` have been completely overhauled. The original functions were unsafe and broken in several ways. See the documentation in `Clash.Xilinx.ClockGen` for how to use the new functions. Significant changes are:
14+
* `clockWizard` and `clockWizardDifferential` now output a `Clock` and a `Reset` which can be directly used by logic. Previously, it outputted a clock and an asynchronous `locked` signal which first needed to be synchronized before it could be used (hence the old function being unsafe). Additionally, the original `locked` signal was strange: it mistakenly was an `Enable` instead of a `Signal dom Bool` and there was a polarity mismatch between Clash simulation and HDL. The `locked` signal was also not resampled to the output domain in Clash simulation.
15+
* There are new functions `unsafeClockWizard` and `unsafeClockWizardDifferential` for advanced use cases which directly expose the `locked` output of the wizard.
16+
* All clock generators now have the option to output multiple clocks from a single instance.
17+
* `clockWizardDifferential` now gets its input clock as a `DiffClock` type; use `clockToDiffClock` to generate this in your test bench if needed. Previously, the function received two clock inputs, but this generated `create_clock` statements in the top-level SDC file for both phases which is incorrect.
18+
* A constraint was removed: The /output/ clock domain no longer requires asynchronous resets. This was originally intended to signal that the outgoing lock signal is an asynchronous signal. The constraint does not convey this information at all and is wrong; it also prevents using synchronous resets in the circuit as recommended by Xilinx. Note that if you use the `unsafe` functions, it is still necessary to synchronize the `locked` output in your design.
19+
* The port names of the primitives in HDL are now correctly lower case.
20+
* Add Tcl generation. This moves the responsibility of MMCM component generation from the user to `clashConnector.tcl`, which can be found in [`clash-lib:Clash.DataFiles`](https://hackage.haskell.org/package/clash-lib-1.8.0/docs/Clash-DataFiles.html).
21+
* The wizards now use the user-provided name as the name of the /instance/ rather than the name of the /IP core/. This change was also done for `Clash.Intel.ClockGen` in Clash v1.2.0 in March 2020, when Clash started generating Intel Qsys files. Before that, the user needed to generate a Qsys component manually. Now, in Clash v1.8.0, we also generate the Tcl for Xilinx wizards. When the user is responsible for creating the IP core, it makes sense to always set the component name to the user-provided value. But when that is also generated by Clash, that is no longer needed. Allowing users to set the instance name instead makes it possible to match on the instance in SDC files and such.

clash-lib/src/Clash/DataFiles.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,10 @@ import Paths_clash_lib (getDataFileName)
4646
> route_design
4747
> write_bitstream ${clash::topEntity}.bit
4848
49-
@clash-cores:Clash.Cores.Xilinx@ modules make use of the IP instantiating
50-
functionality; XDC metadata functionality is not currently used as the IP is
51-
already packaged with correct constraints by Vivado.
49+
"Clash.Xilinx.ClockGen" and @clash-cores:Clash.Cores.Xilinx@
50+
modules make use of the IP instantiating functionality; XDC metadata
51+
functionality is not currently used as the IP is already packaged with correct
52+
constraints by Vivado.
5253
5354
More documentation about the Tcl Connector and the Clash\<->Tcl API will be
5455
made available later.

clash-prelude/src/Clash/Annotations/TopEntity.hs

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-|
22
Copyright : (C) 2015-2016, University of Twente,
33
2017 , Google Inc.,
4-
2021-2022, QBayLogic B.V.
4+
2021-2023, QBayLogic B.V.
55
License : BSD2 (see the file LICENSE)
66
Maintainer : QBayLogic B.V. <[email protected]>
77
@@ -62,7 +62,11 @@ module Blinker where
6262
import Clash.Prelude
6363
import Clash.Intel.ClockGen
6464
65-
'Clash.Explicit.Signal.createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}
65+
-- Define a synthesis domain with a clock with a period of 20000 /ps/. Signal
66+
-- coming from the reset button is low when pressed, and high when not pressed.
67+
'Clash.Explicit.Signal.createDomain'
68+
vSystem{vName=\"DomInput\", vPeriod=20000, vResetPolarity=ActiveLow}
69+
-- Define a synthesis domain with a clock with a period of 50000 /ps/.
6670
'Clash.Explicit.Signal.createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}
6771
6872
topEntity
@@ -75,35 +79,19 @@ topEntity clk20 rstBtn enaBtn modeBtn =
7579
'Clash.Signal.exposeClockResetEnable'
7680
('Clash.Prelude.mealy' blinkerT initialStateBlinkerT . 'Clash.Prelude.isRising' 1)
7781
clk50
78-
rstSync
82+
rst50
7983
enaBtn
8084
modeBtn
8185
where
8286
-- Start with the first LED turned on, in rotate mode, with the counter on zero
8387
initialStateBlinkerT = (1, False, 0)
8488
85-
-- Signal coming from the reset button is low when pressed, and high when
86-
-- not pressed. We convert this signal to the polarity of our domain with
87-
-- /unsafeFromActiveLow/.
88-
rst = 'Clash.Signal.unsafeFromActiveLow' ('Clash.Signal.unsafeFromReset' rstBtn)
89-
90-
-- Instantiate a PLL: this stabilizes the incoming clock signal and indicates
91-
-- when the signal is stable. We're also using it to transform an incoming
92-
-- clock signal running at 20 MHz to a clock signal running at 50 MHz.
93-
(clk50, pllStable) =
94-
'Clash.Intel.ClockGen.altpll'
95-
\@Dom50
96-
(SSymbol @"altpll50")
97-
clk20
98-
rst
99-
100-
-- Synchronize reset to clock signal coming from PLL. We want the reset to
101-
-- remain active while the PLL is NOT stable, hence the conversion with
102-
-- /unsafeFromActiveLow/
103-
rstSync =
104-
'Clash.Prelude.resetSynchronizer'
105-
clk50
106-
('Clash.Signal.unsafeFromActiveLow' pllStable)
89+
-- Instantiate a PLL: this stabilizes the incoming clock signal and releases
90+
-- the reset output when the signal is stable. We're also using it to
91+
-- transform an incoming clock signal running at 20 MHz to a clock signal
92+
-- running at 50 MHz. Since the signature of topEntity already specifies the
93+
-- Dom50 domain, we don't need any type signatures to specify the domain here.
94+
(clk50, rst50) = 'Clash.Intel.ClockGen.altpllSync' clk20 rstBtn
10795
10896
blinkerT
10997
:: (BitVector 8, Bool, Index 16650001)

clash-prelude/src/Clash/Explicit/Reset.hs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,23 @@ unsafeAndReset (unsafeFromReset -> rst0) (unsafeFromReset -> rst1) =
158158
-- === __Example 2__
159159
-- Similar to /Example 1/ this circuit detects a rising bit (i.e., a transition
160160
-- from 0 to 1) in a given argument. It takes a clock that is not stable yet and
161-
-- a reset singal that is not synchronized to any other signals. It stabalizes
161+
-- a reset signal that is not synchronized to any other signals. It stabilizes
162162
-- the clock and then synchronizes the reset signal.
163163
--
164+
--
165+
-- Note that the function 'Clash.Intel.ClockGen.altpllSync' provides this
166+
-- functionality in a convenient form, obviating the need for
167+
-- @resetSynchronizer@ for this use case.
168+
--
164169
-- @
165170
-- topEntity
166171
-- :: Clock System
167172
-- -> Reset System
168173
-- -> Signal System Bit
169174
-- -> Signal System (BitVector 8)
170175
-- topEntity clk rst key1 =
171-
-- let (pllOut,pllStable) = altpll (SSymbol @"altpll50") clk rst
172-
-- rstSync = 'resetSynchronizer' pllOut (unsafeToActiveHigh pllStable)
176+
-- let (pllOut,pllStable) = unsafeAltpll clk rst
177+
-- rstSync = 'resetSynchronizer' pllOut (unsafeFromActiveLow pllStable)
173178
-- in exposeClockResetEnable leds pllOut rstSync enableGen
174179
-- where
175180
-- key1R = isRising 1 key1

0 commit comments

Comments
 (0)