Skip to content

Commit 82442bb

Browse files
New: DiffClock (#2529)
A new type is introduced to signify a differential clock signal that is passed to the design on two ports in antiphase. This is used by Xilinx `clockWizardDifferential` (note that Intel solves this case differently, so if we were to add an Intel primitive it would not need this type). With this new type, we prevent the creation of more `create_clock` statements in the global SDC file than is correct: only the positive phase of a differential pair should have a `create_clock` statement. Fixes #2518
1 parent 955ec40 commit 82442bb

File tree

23 files changed

+189
-102
lines changed

23 files changed

+189
-102
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
ADDED: A new clock type `DiffClock` is introduced to signify a differential
2+
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 `seClockToDiffClock` 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.

clash-ghc/src-ghc/Clash/GHC/NetlistTypes.hs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-|
22
Copyright : (C) 2013-2016, University of Twente,
33
2016-2023, Myrtle Software Ltd,
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
-}
@@ -185,6 +185,12 @@ ghcTypeToHWType iw = go
185185
tag1 <- domTag m tag0
186186
returnN (Clock (pack tag1))
187187

188+
"Clash.Signal.Internal.ClockN"
189+
| [tag0] <- args
190+
-> do
191+
tag1 <- domTag m tag0
192+
returnN (ClockN (pack tag1))
193+
188194
"Clash.Signal.Internal.Reset"
189195
| [tag0] <- args
190196
-> do
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
- BlackBox:
2+
name: Clash.Xilinx.ClockGen.clockWizardDifferential
3+
kind: Declaration
4+
format: Haskell
5+
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardDifferentialTF
6+
includes:
7+
- name: clk_wiz
8+
extension: clash.tcl
9+
format: Haskell
10+
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardDifferentialTclTF
11+
workInfo: Always

clash-lib/prims/commonverilog/Clash_Explicit_Testbench.primitives.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@
88
- BlackBox:
99
name: Clash.Explicit.Testbench.seClockToDiffClock
1010
kind: Expression
11-
template: '{~ARG[0], ~ ~ARG[0]}'
11+
template: '{~ARG[1], ~ ~ARG[1]}'

clash-lib/prims/commonverilog/Clash_Xilinx_ClockGen.primitives.yaml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,3 @@
2323
format: Haskell
2424
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardTclTF
2525
workInfo: Always
26-
- BlackBox:
27-
name: Clash.Xilinx.ClockGen.clockWizardDifferential
28-
kind: Declaration
29-
type: |-
30-
clockWizardDifferential
31-
:: ( KnownDomain domIn -- ARG[0]
32-
, KnownDomain domOut ) -- ARG[1]
33-
:: SSymbol name -- ARG[2]
34-
-> Clock domIn -- ARG[3]
35-
-> Clock domIn -- ARG[4]
36-
-> Reset domIn -- ARG[5]
37-
-> (Clock domOut, Signal domOut Bool)
38-
template: |-
39-
// clockWizardDifferential begin
40-
~NAME[2] ~GENSYM[clockWizardDifferential_inst][2]
41-
(.clk_in1_n (~ARG[3])
42-
,.clk_in1_p (~ARG[4])
43-
,.reset (~IF ~ISACTIVEHIGH[0] ~THEN ~ELSE ! ~FI ~ARG[5])
44-
,.clk_out1 (~RESULT[1])
45-
,.locked (~RESULT[0]));
46-
// clockWizardDifferential end
47-
includes:
48-
- name: clk_wiz
49-
extension: clash.tcl
50-
format: Haskell
51-
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardDifferentialTclTF
52-
workInfo: Always

clash-lib/prims/vhdl/Clash_Explicit_Testbench.primitives.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,4 +158,4 @@
158158
- BlackBox:
159159
name: Clash.Explicit.Testbench.seClockToDiffClock
160160
kind: Expression
161-
template: (~ARG[0], not ~ARG[0])
161+
template: (~ARG[1], not ~ARG[1])

clash-lib/prims/vhdl/Clash_Xilinx_ClockGen.primitives.yaml

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,41 +34,3 @@
3434
format: Haskell
3535
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardTclTF
3636
workInfo: Always
37-
- BlackBox:
38-
name: Clash.Xilinx.ClockGen.clockWizardDifferential
39-
kind: Declaration
40-
type: |-
41-
clockWizard
42-
:: ( KnownDomain domIn -- ARG[0]
43-
, KnownDomain domOut ) -- ARG[1]
44-
=> SSymbol name -- ARG[2]
45-
-> Clock domIn -- ARG[3]
46-
-> Clock domIn -- ARG[4]
47-
-> Reset domIn -- ARG[5]
48-
-> (Clock domOut, Signal domOut Bool)
49-
template: |-
50-
-- clockWizardDifferential begin
51-
~GENSYM[clockWizardDifferential][0] : block
52-
signal ~GENSYM[pllOut][1] : std_logic;
53-
signal ~GENSYM[locked][2] : std_logic;
54-
signal ~GENSYM[pllLock][3] : boolean;
55-
component ~NAME[2]
56-
port (clk_in1_n : in std_logic;
57-
clk_in1_p : in std_logic;
58-
reset : in std_logic;
59-
clk_out1 : out std_logic;
60-
locked : out std_logic);
61-
end component;
62-
begin
63-
~GENSYM[clockWizardDifferential_inst][4] : component ~NAME[2]
64-
port map (~ARG[3],~ARG[4],~IF ~ISACTIVEHIGH[0] ~THEN ~ARG[5] ~ELSE NOT(~ARG[5]) ~FI,~SYM[1],~SYM[2]);
65-
~SYM[3] <= true when ~SYM[2] = '1' else false;
66-
~RESULT <= (~SYM[1],~SYM[3]);
67-
end block;
68-
-- clockWizardDifferential end
69-
includes:
70-
- name: clk_wiz
71-
extension: clash.tcl
72-
format: Haskell
73-
templateFunction: Clash.Primitives.Xilinx.ClockGen.clockWizardDifferentialTclTF
74-
workInfo: Always

clash-lib/src/Clash/Backend/SystemVerilog.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{-|
22
Copyright : (C) 2015-2016, University of Twente,
33
2017-2018, Google Inc.,
4-
2021-2022, QBayLogic B.V.
4+
2021-2023, QBayLogic B.V.,
55
2022 , Google Inc.
66
License : BSD2 (see the file LICENSE)
77
Maintainer : QBayLogic B.V. <[email protected]>
@@ -330,6 +330,7 @@ normaliseType ty@(Index _) = return (Unsigned (typeSize ty))
330330
normaliseType ty@(Sum _ _) = return (BitVector (typeSize ty))
331331
normaliseType ty@(CustomSum _ _ _ _) = return (BitVector (typeSize ty))
332332
normaliseType (Clock _) = return Bit
333+
normaliseType (ClockN _) = return Bit
333334
normaliseType (Reset _) = return Bit
334335
normaliseType (Enable _) = return Bool
335336
normaliseType (BiDirectional dir ty) = BiDirectional dir <$> normaliseType ty
@@ -394,6 +395,7 @@ splitVecTy = fmap splitElemTy . go
394395
Product {} -> (ns, verilogType t)
395396
Vector {} -> error $ $(curLoc) ++ "impossible"
396397
Clock {} -> (ns, verilogType t)
398+
ClockN {} -> (ns, verilogType t)
397399
Reset {} -> (ns, "logic")
398400
Enable {} -> (ns, "logic")
399401
Bool -> (ns, "logic")
@@ -596,6 +598,7 @@ verilogType t_ = do
596598
RTree {} -> pvrType
597599
Signed n -> logicOrWire <+> "signed" <+> brackets (int (n-1) <> colon <> int 0)
598600
Clock _ -> "logic"
601+
ClockN _ -> "logic"
599602
Reset _ -> "logic"
600603
Enable _ -> "logic"
601604
Bit -> "logic"
@@ -645,6 +648,7 @@ tyName t@(Product nm _ _) = do
645648

646649
tyName t@(SP _ _) = "logic_vector_" <> int (typeSize t)
647650
tyName (Clock _) = "logic"
651+
tyName (ClockN _) = "logic"
648652
tyName (Reset _) = "logic"
649653
tyName (Enable _) = "logic"
650654
tyName t = error $ $(curLoc) ++ "tyName: " ++ show t

clash-lib/src/Clash/Backend/VHDL.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ instance Backend VHDLState where
177177
if enums then pure UserType else pure SynonymType
178178

179179
Clock {} -> pure SynonymType
180+
ClockN {} -> pure SynonymType
180181
Reset {} -> pure SynonymType
181182
Enable {} -> pure SynonymType
182183
Index {} -> pure SynonymType
@@ -602,6 +603,7 @@ tyDec hwty = do
602603

603604
-- Type aliases:
604605
Clock _ -> typAliasDec hwty
606+
ClockN _ -> typAliasDec hwty
605607
Reset _ -> typAliasDec hwty
606608
Enable _ -> typAliasDec hwty
607609
Index _ -> typAliasDec hwty
@@ -1196,6 +1198,9 @@ tyName' rec0 (filterTransparent -> t) = do
11961198
Clock nm0 ->
11971199
let nm1 = "clk_" `TextS.append` nm0 in
11981200
Ap $ makeCached (t, False) nameCache (userTyName "clk" nm1 t)
1201+
ClockN nm0 ->
1202+
let nm1 = "clk_n_" `TextS.append` nm0 in
1203+
Ap $ makeCached (t, False) nameCache (userTyName "clk" nm1 t)
11991204
Reset nm0 ->
12001205
let nm1 = "rst_" `TextS.append` nm0 in
12011206
Ap $ makeCached (t, False) nameCache (userTyName "rst" nm1 t)
@@ -1248,6 +1253,7 @@ normaliseType enums@(RenderEnums e) hwty = case hwty of
12481253

12491254
-- Simple types, for which a subtype (without qualifiers) will be made in VHDL:
12501255
Clock _ -> Bit
1256+
ClockN _ -> Bit
12511257
Reset _ -> Bit
12521258
Enable _ -> Bool
12531259
Index _ -> Unsigned (typeSize hwty)
@@ -1271,6 +1277,7 @@ filterTransparent hwty = case hwty of
12711277
Integer -> hwty
12721278
Bit -> hwty
12731279
Clock _ -> hwty
1280+
ClockN _ -> hwty
12741281
Reset _ -> hwty
12751282
Enable _ -> hwty
12761283
Index _ -> hwty
@@ -1349,6 +1356,7 @@ sizedQualTyNameErrValue t@(Sum _ _) = do
13491356
else
13501357
qualTyName t <> "'" <> parens (int 0 <+> "to" <+> int (typeSize t - 1) <+> rarrow <+> singularErrValue)
13511358
sizedQualTyNameErrValue (Clock _) = singularErrValue
1359+
sizedQualTyNameErrValue (ClockN _) = singularErrValue
13521360
sizedQualTyNameErrValue (Reset _) = singularErrValue
13531361
sizedQualTyNameErrValue (Enable _) = singularErrValue
13541362
sizedQualTyNameErrValue (Void {}) =
@@ -1948,6 +1956,9 @@ toSLV Bit e = do
19481956
toSLV (Clock {}) e = do
19491957
nm <- Ap $ use modNm
19501958
pretty nm <> "_types.toSLV" <> parens (expr_ False e)
1959+
toSLV (ClockN {}) e = do
1960+
nm <- Ap $ use modNm
1961+
pretty nm <> "_types.toSLV" <> parens (expr_ False e)
19511962
toSLV (Reset {}) e = do
19521963
nm <- Ap $ use modNm
19531964
pretty (TextS.toLower nm) <> "_types.toSLV" <> parens (expr_ False e)
@@ -2034,6 +2045,7 @@ punctuate' s d = vcat (punctuate s d) <> s
20342045

20352046
encodingNote :: HWType -> VHDLM Doc
20362047
encodingNote (Clock _) = "-- clock" <> line
2048+
encodingNote (ClockN _) = "-- clock (neg phase)" <> line
20372049
encodingNote (Reset _) = "-- reset" <> line
20382050
encodingNote (Enable _) = "-- enable" <> line
20392051
encodingNote (Annotated _ t) = encodingNote t

clash-lib/src/Clash/Backend/Verilog.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ verilogType :: HWType -> VerilogM Doc
366366
verilogType t = case t of
367367
Signed n -> "signed" <+> brackets (int (n-1) <> colon <> int 0)
368368
Clock {} -> emptyDoc
369+
ClockN {} -> emptyDoc
369370
Reset {} -> emptyDoc
370371
Enable {} -> emptyDoc
371372
Bit -> emptyDoc
@@ -1283,6 +1284,7 @@ punctuate' s d = vcat (punctuate s d) <> s
12831284

12841285
encodingNote :: Applicative m => HWType -> m Doc
12851286
encodingNote (Clock _) = string " // clock"
1287+
encodingNote (ClockN _) = string " // clock (neg phase)"
12861288
encodingNote (Reset _) = string " // reset"
12871289
encodingNote (Enable _) = string " // enable"
12881290
encodingNote (Annotated _ t) = encodingNote t

0 commit comments

Comments
 (0)