packages feed

clash-prelude 1.8.1 → 1.8.2

raw patch · 45 files changed

+1062/−741 lines, 45 filesdep +taggeddep ~data-default-classdep ~extradep ~ghc-primPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: tagged

Dependency ranges changed: data-default-class, extra, ghc-prim, hedgehog, template-haskell

API changes (from Hackage documentation)

- Clash.Class.BitPack.Internal: xToBV :: KnownNat n => BitVector n -> BitVector n
+ Clash.Class.Exp: infixr 8 ^
+ Clash.Class.Num: infixl 6 `boundedSub`
+ Clash.Class.Num: infixl 7 `boundedMul`
+ Clash.Sized.Internal.BitVector: xToBV :: KnownNat n => BitVector n -> BitVector n
+ Clash.Sized.Vector.ToTuple: class VecToTuple a where {
+ Clash.Sized.Vector.ToTuple: instance Clash.Sized.Vector.ToTuple.VecToTuple (Clash.Sized.Vector.Vec 0 a)
+ Clash.Sized.Vector.ToTuple: instance Clash.Sized.Vector.ToTuple.VecToTuple (Clash.Sized.Vector.Vec 2 a)
+ Clash.Sized.Vector.ToTuple: instance Clash.Sized.Vector.ToTuple.VecToTuple (Clash.Sized.Vector.Vec 3 a)
+ Clash.Sized.Vector.ToTuple: type family TupType a = r | r -> a;
+ Clash.Sized.Vector.ToTuple: vecToTuple :: VecToTuple a => a -> TupType a
+ Clash.Sized.Vector.ToTuple: }
+ Clash.XException: instance Clash.XException.NFDataX (Data.Proxy.Proxy a)
+ Clash.XException: instance Clash.XException.ShowX (Data.Proxy.Proxy a)

Files

CHANGELOG.md view
@@ -1,5 +1,34 @@ # Changelog for the Clash project +## 1.8.2 *Jan 3rd 2025*++Added:+* Support for GHC 9.10 [#2758](https://github.com/clash-lang/clash-compiler/pull/2758)+* Support for GHC 9.8.4 [#2852](https://github.com/clash-lang/clash-compiler/issues/2852)+* Add `ShowX`, `NFDataX` instances for `Proxy` [#2637](https://github.com/clash-lang/clash-compiler/pull/2637)+* Added `Clash.Sized.Vector.ToTuple.vecToTuple`: a way to safely work around incomplete patterns warnings on patterns involving `Vec`tors. [#2862](https://github.com/clash-lang/clash-compiler/pull/2682)+* Added operator precedences for infix usage of functions exported from `Clash.Class.Num`: `mul`, `add`, `sub`, `satMul`, `satAdd`, `satSub`, `boundedMul`, `boundedAdd`, and `boundedSub`. This means that expressions such as `` a `add` b `mul` c `` now get parsed as `` a `add` (b `mul` c) `` instead of `` (a `add` b) `mul` c ``. [#2719](https://github.com/clash-lang/clash-compiler/pull/2719)++Changed:+* `BitVector n` now has an implementation for `ensureSpine` which ensures the constructor is present. [#2702](https://github.com/clash-lang/clash-compiler/pull/2702)+* `xToBV` is now located in `Clash.Sized.Internal.BitVector` to avoid circular dependencies. [#2702](https://github.com/clash-lang/clash-compiler/pull/2702)+* The error messages that mention the valid ranges for out-of-range inputs have been improved to be more intuitive: one of `<empty range>`, `[n]` or `[n..m]`. All _n..m_ ranges are now ordered with the lower bound on the left. [#2733](https://github.com/clash-lang/clash-compiler/pull/2733)++Fixed:+* cabal: Make `workaround-ghc-mmap-crash` a noop on non-x86_64. Fixes [#2656](https://github.com/clash-lang/clash-compiler/issues/2656)+* Clash no longer hides error messages if it fails to load external (precompiled) modules. Note: this fix only works from GHC 9.0 on. See [#2365](https://github.com/clash-lang/clash-compiler/issues/2365)+* HDL generation fails when using multiple-hidden feature in combination with synthesis attributes [#2593](https://github.com/clash-lang/clash-compiler/issues/2593)+* Clash no longer errors out in the netlist generation stage when a polymorphic function is applied to type X in one alternative of a case-statement and applied to a newtype wrapper of type X in a different alternative. See [#2828](https://github.com/clash-lang/clash-compiler/issues/2628)+* various issues with black boxes and evaluator rules for number-related primitives [#2689](https://github.com/clash-lang/clash-compiler/pull/2689)+* `genBitVector` no longer contains off-by-one error on for generated Naturals [#2704](https://github.com/clash-lang/clash-compiler/pull/2704)+* (+>>.) and (.<<+) such that they are compliant with (+>>) and (<<+) for vectors of zero length in the sense that the input vector is kept unchanged. [#2730](https://github.com/clash-lang/clash-compiler/issues/2730)+* Removed `stringsearch` dependency from `v16-upgrade-primitives`. See [#2726](https://github.com/clash-lang/clash-compiler/issues/2726)+* Bug in the compile-time evaluator [#2781](https://github.com/clash-lang/clash-compiler/issues/2781)+* Exponentiation (`Clash.Class.Exp`) is now right-associative with a precedence level of 8 (`infixr 8`). By accident, it used to lack a fixity declaration, meaning it was implicitly left-associative at level 9. [#2818](https://github.com/clash-lang/clash-compiler/pull/2818)+* Unused argument warnings on writeToBiSignal# [#2822](https://github.com/clash-lang/clash-compiler/pull/2822)+* Clash errored saying it cannot translate a globally recursive function in code that originally only contains let-bound (local) recursion [#2839](https://github.com/clash-lang/clash-compiler/issues/2839)+* Clash generates illegal Verilog names [#2845](https://github.com/clash-lang/clash-compiler/issues/2845)+ ## 1.8.1 *Nov 10th 2023*  * Bump package dependencies to allow inclusion in stackage-nightly
clash-prelude.cabal view
@@ -1,6 +1,6 @@ Cabal-version:        2.2 Name:                 clash-prelude-Version:              1.8.1+Version:              1.8.2 Synopsis:             Clash: a functional hardware description language - Prelude library Description:   Clash is a functional hardware description language that borrows both its@@ -285,6 +285,8 @@                       Clash.Sized.Signed                       Clash.Sized.Unsigned                       Clash.Sized.Vector+                      Clash.Sized.Vector.ToTuple+                      Clash.Sized.Vector.ToTuple.TH                        Clash.Sized.Internal.BitVector                       Clash.Sized.Internal.Index@@ -313,6 +315,7 @@                       Clash.Clocks.Internal                       Clash.CPP                       Clash.Signal.Bundle.Internal+                      Clash.Sized.Internal                       Language.Haskell.TH.Compat                       Paths_clash_prelude @@ -335,7 +338,7 @@                       binary                    >= 0.8.5   && < 0.11,                       bytestring                >= 0.10.8  && < 0.13,                       constraints               >= 0.9     && < 1.0,-                      containers                >= 0.4.0   && < 0.7,+                      containers                >= 0.4.0   && < 0.8,                       data-binary-ieee754       >= 0.4.4   && < 0.6,                       data-default-class        >= 0.1.2   && < 0.2,                       deepseq                   >= 1.4.1.0 && < 1.6,@@ -344,21 +347,22 @@                       ghc-typelits-extra        >= 0.4     && < 0.5,                       ghc-typelits-knownnat     >= 0.7.2   && < 0.8,                       ghc-typelits-natnormalise >= 0.7.2   && < 0.8,-                      hashable                  >= 1.2.1.0  && < 1.5,+                      hashable                  >= 1.2.1.0  && < 1.6,                       half                      >= 0.2.2.3 && < 1.0,                       infinite-list           ^>= 0.1,-                      lens                      >= 4.10    && < 5.3,-                      QuickCheck                >= 2.7     && < 2.15,+                      lens                      >= 4.10    && < 5.4,+                      QuickCheck                >= 2.7     && < 2.16,                       recursion-schemes         >= 5.1     && < 5.3,                       reflection                >= 2       && < 2.2,                       singletons                >= 2.0     && < 3.1,                       string-interpolate        ^>= 0.3,-                      template-haskell          >= 2.12.0.0 && < 2.22,-                      th-abstraction            >= 0.2.10 && < 0.7.0,+                      tagged                    >= 0.8     && < 0.9,+                      template-haskell          >= 2.12.0.0 && < 2.23,+                      th-abstraction            >= 0.2.10 && < 0.8.0,                       th-lift                   >= 0.7.0    && < 0.9,                       th-orphans                >= 0.13.1   && < 1.0,                       text                      >= 0.11.3.1 && < 2.2,-                      time                      >= 1.8     && < 1.14,+                      time                      >= 1.8     && < 1.15,                       transformers              >= 0.5.2.0 && < 0.7,                       type-errors               >= 0.2.0.0 && < 0.3,                       uniplate                  >= 1.6.12  && < 1.7,@@ -388,7 +392,7 @@       doctest-parallel >= 0.2 && < 0.4,       filepath -  if flag(workaround-ghc-mmap-crash)+  if arch(x86_64) && flag(workaround-ghc-mmap-crash)     ghc-options:    -with-rtsopts=-xm20000000  @@ -398,7 +402,7 @@   main-is:          unittests.hs   ghc-options:      -Wall -Wcompat -threaded   -- Note that multiple -with-rtsopts are not cumulative-  if flag(workaround-ghc-mmap-crash)+  if arch(x86_64) && flag(workaround-ghc-mmap-crash)     ghc-options:    "-with-rtsopts=-N -xm20000000"   else     ghc-options:    -with-rtsopts=-N
src/Clash/Annotations/Primitive.hs view
@@ -201,10 +201,8 @@ -- -- You create a package which has a @myfancyip.cabal@ file with the following stanza: ----- @--- data-files: path\/to\/MyFancyIP.primitives--- cpp-options: -DCABAL--- @+-- > data-files: path/to/MyFancyIP.primitives+-- > cpp-options: -DCABAL -- -- and a @MyFancyIP.hs@ module with the simulation definition and primitive. --
src/Clash/Annotations/SynthesisAttributes.hs view
@@ -41,11 +41,9 @@ -- | Synthesis attributes are directives passed to synthesis tools, such as -- Quartus. An example of such an attribute in VHDL: ----- @---   attribute chip_pin : string;---   attribute chip_pin of sel : signal is \"C4\";---   attribute chip_pin of data : signal is "D1, D2, D3, D4";--- @+-- > attribute chip_pin : string;+-- > attribute chip_pin of sel : signal is "C4";+-- > attribute chip_pin of data : signal is "D1, D2, D3, D4"; -- -- This would instruct the synthesis tool to map the wire /sel/ to pin /C4/, and -- wire /data/ to pins /D1/, /D2/, /D3/, and /D4/. To achieve this in Clash, /Attr/s@@ -92,7 +90,7 @@ -- @ -- f :: Signal System Bool \`Annotate\` 'StringAttr \"chip_pin\" \"C4\" --   -> Signal System Bool--- f x = id x -- Using a lambda, i.e. f = \x -> id x also works+-- f x = id x -- Using a lambda, i.e. f = \\x -> id x also works -- @ -- -- will reliably show the annotation in the generated HDL, but
src/Clash/Annotations/TopEntity.hs view
@@ -62,11 +62,11 @@ import Clash.Prelude import Clash.Intel.ClockGen --- Define a synthesis domain with a clock with a period of 20000 /ps/. Signal+-- Define a synthesis domain with a clock with a period of 20000 \/ps\/. Signal -- coming from the reset button is low when pressed, and high when not pressed. 'Clash.Explicit.Signal.createDomain'   vSystem{vName=\"DomInput\", vPeriod=20000, vResetPolarity=ActiveLow}--- Define a synthesis domain with a clock with a period of 50000 /ps/.+-- Define a synthesis domain with a clock with a period of 50000 \/ps\/. 'Clash.Explicit.Signal.createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}  topEntity@@ -117,31 +117,29 @@ The Clash compiler would normally generate the following @topEntity.vhdl@ file: -@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.Blinker_topEntity_types.all;--entity topEntity is-  port(-- clock-       clk20   : in Blinker_topEntity_types.clk_DomInput;-       -- reset-       rstBtn  : in Blinker_topEntity_types.rst_DomInput;-       -- enable-       enaBtn  : in Blinker_topEntity_types.en_Dom50;-       modeBtn : in std_logic;-       result  : out std_logic_vector(7 downto 0));-end;--architecture structural of topEntity is-  ...-end;-@+> -- Automatically generated VHDL-93+> library IEEE;+> use IEEE.STD_LOGIC_1164.ALL;+> use IEEE.NUMERIC_STD.ALL;+> use IEEE.MATH_REAL.ALL;+> use std.textio.all;+> use work.all;+> use work.Blinker_topEntity_types.all;+>+> entity topEntity is+>   port(-- clock+>        clk20   : in Blinker_topEntity_types.clk_DomInput;+>        -- reset+>        rstBtn  : in Blinker_topEntity_types.rst_DomInput;+>        -- enable+>        enaBtn  : in Blinker_topEntity_types.en_Dom50;+>        modeBtn : in std_logic;+>        result  : out std_logic_vector(7 downto 0));+> end;+>+> architecture structural of topEntity is+>   ...+> end;  However, if we add the following 'Synthesize' annotation in the file: @@ -159,31 +157,29 @@  The Clash compiler will generate the following @blinker.vhdl@ file instead: -@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.blinker_types.all;--entity blinker is-  port(-- clock-       CLOCK_50 : in blinker_types.clk_DomInput;-       -- reset-       KEY0     : in blinker_types.rst_DomInput;-       -- enable-       KEY1     : in blinker_types.en_Dom50;-       KEY2     : in std_logic;-       LED      : out std_logic_vector(7 downto 0));-end;--architecture structural of blinker is-  ...-end;-@+> -- Automatically generated VHDL-93+> library IEEE;+> use IEEE.STD_LOGIC_1164.ALL;+> use IEEE.NUMERIC_STD.ALL;+> use IEEE.MATH_REAL.ALL;+> use std.textio.all;+> use work.all;+> use work.blinker_types.all;+>+> entity blinker is+>   port(-- clock+>        CLOCK_50 : in blinker_types.clk_DomInput;+>        -- reset+>        KEY0     : in blinker_types.rst_DomInput;+>        -- enable+>        KEY1     : in blinker_types.en_Dom50;+>        KEY2     : in std_logic;+>        LED      : out std_logic_vector(7 downto 0));+> end;+>+> architecture structural of blinker is+>   ...+> end;  Where we now have: @@ -293,14 +289,12 @@ -- -- Clash would normally generate the following VHDL entity: ----- @--- entity f is---   port(a      : in signed(63 downto 0);---        b_0    : in signed(63 downto 0);---        b_1    : in boolean;---        result : out std_logic_vector(65 downto 0));--- end;--- @+-- > entity f is+-- >   port(a      : in signed(63 downto 0);+-- >        b_0    : in signed(63 downto 0);+-- >        b_1    : in boolean;+-- >        result : out std_logic_vector(65 downto 0));+-- > end; -- -- However, we can change this by using 'PortName's. So by: --@@ -317,13 +311,11 @@ -- -- we get: ----- @--- entity f is---   port(a   : in signed(63 downto 0);---        b   : in std_logic_vector(64 downto 0);---        res : out std_logic_vector(65 downto 0));--- end;--- @+-- > entity f is+-- >   port(a   : in signed(63 downto 0);+-- >        b   : in std_logic_vector(64 downto 0);+-- >        res : out std_logic_vector(65 downto 0));+-- > end; -- -- If we want to name fields for tuples/records we have to use 'PortProduct' --@@ -340,15 +332,13 @@ -- -- So that we get: ----- @--- entity f is---   port(a     : in signed(63 downto 0);---        b     : in signed(63 downto 0);---        c     : in boolean;---        res_q : out std_logic_vector(64 downto 0);---        res_1 : out boolean);--- end;--- @+-- > entity f is+-- >   port(a     : in signed(63 downto 0);+-- >        b     : in signed(63 downto 0);+-- >        c     : in boolean;+-- >        res_q : out std_logic_vector(64 downto 0);+-- >        res_1 : out boolean);+-- > end; -- -- Notice how we didn't name the second field of the result, and the second -- output port got 'PortProduct' name, \"res\", as a prefix for its name.
src/Clash/Class/BitPack/BitIndex.hs view
@@ -1,6 +1,6 @@ {-| Copyright  :  (C) 2013-2016, University of Twente-                       2021, QBayLogic B.V.+                  2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -39,7 +39,7 @@ -- >>> (7 :: Unsigned 6) ! 5 -- 0 -- >>> (7 :: Unsigned 6) ! 6--- *** Exception: (!): 6 is out of range [5..0]+-- *** Exception: (!): 6 is out of range [0..5] -- ... (!) :: (BitPack a, Enum i) => a -> i -> Bit (!) v i = index# (pack v) (fromEnum i)@@ -54,9 +54,19 @@ >>> slice d4 d2 (7 :: Unsigned 6) 0b001 -#if __GLASGOW_HASKELL__ == 906+#if __GLASGOW_HASKELL__ >= 910 >>> slice d6 d4 (7 :: Unsigned 6)+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘slice’+      The type variable ‘i0’ is ambiguous+    • In the expression: slice d6 d4 (7 :: Unsigned 6)+      In an equation for ‘it’: it = slice d6 d4 (7 :: Unsigned 6) <BLANKLINE>++#elif __GLASGOW_HASKELL__ == 906+>>> slice d6 d4 (7 :: Unsigned 6)+<BLANKLINE> <interactive>:...     • Couldn't match type ‘7 + i0’ with ‘6’         arising from a use of ‘slice’@@ -114,7 +124,7 @@ -- >>> pack (27 :: Signed 6) -- 0b01_1011 -- >>> replaceBit 6 0 (-5 :: Signed 6)--- *** Exception: replaceBit: 6 is out of range [5..0]+-- *** Exception: replaceBit: 6 is out of range [0..5] -- ... replaceBit :: (BitPack a, Enum i) => i -> Bit -> a -> a replaceBit i b v = unpack (replaceBit# (pack v) (fromEnum i) b)@@ -131,7 +141,17 @@ >>> pack (-29 :: Signed 6) 0b10_0011 -#if __GLASGOW_HASKELL__ == 906+#if __GLASGOW_HASKELL__ >= 910+>>> setSlice d6 d5 0 (-5 :: Signed 6)+<interactive>:...+    • Couldn't match type ‘7 + i0’ with ‘6’+        arising from a use of ‘setSlice’+      The type variable ‘i0’ is ambiguous+    • In the expression: setSlice d6 d5 0 (- 5 :: Signed 6)+      In an equation for ‘it’: it = setSlice d6 d5 0 (- 5 :: Signed 6)+<BLANKLINE>++#elif __GLASGOW_HASKELL__ == 906 >>> setSlice d6 d5 0 (-5 :: Signed 6) <BLANKLINE> <interactive>:...
src/Clash/Class/BitPack/Internal.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2017, Myrtle Software Ltd,-                  2021-2023  QBayLogic B.V.,+                  2021-2024  QBayLogic B.V.,                   2022,      Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>@@ -26,7 +26,6 @@  import Prelude                        hiding (map) -import Control.Exception              (catch, evaluate) import Data.Binary.IEEE754            (doubleToWord, floatToWord, wordToDouble,                                        wordToFloat) @@ -44,7 +43,6 @@ import GHC.TypeLits                   (KnownNat, Nat, type (+), type (-)) import GHC.TypeLits.Extra             (CLog, Max) import Numeric.Half                   (Half (..))-import System.IO.Unsafe               (unsafeDupablePerformIO)  import Clash.Annotations.Primitive    (hasBlackBox) import Clash.Class.BitPack.Internal.TH (deriveBitPackTuples)@@ -52,8 +50,7 @@ import Clash.Promoted.Nat             (SNat(..), snatToNum) import Clash.Sized.Internal.BitVector   (pack#, split#, checkUnpackUndef, undefined#, unpack#, unsafeToNatural, isLike#,-   BitVector, Bit, (++#))-import Clash.XException+   BitVector, Bit, (++#), xToBV)  {- $setup >>> :m -Prelude@@ -163,14 +160,6 @@   -> BitVector n packXWith f = xToBV . f {-# INLINE packXWith #-}--xToBV :: KnownNat n => BitVector n -> BitVector n-xToBV x =-  unsafeDupablePerformIO (catch (evaluate x)-                                (\(XException _) -> return undefined#))--- See: https://github.com/clash-lang/clash-compiler/pull/2511-{-# CLASH_OPAQUE xToBV #-}-{-# ANN xToBV hasBlackBox #-}  -- | Pack both arguments to a 'BitVector' and use -- 'Clash.Sized.Internal.BitVector.isLike#' to compare them. This is a more
src/Clash/Class/BitPack/Internal/TH.hs view
@@ -1,5 +1,5 @@ {-|-Copyright  :  (C) 2019, QBayLogic B.V.+Copyright  :  (C) 2019-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -11,7 +11,9 @@ import           Clash.CPP             (maxTupleSize) import           Language.Haskell.TH.Compat (mkTySynInstD,mkTupE) import           Control.Monad         (replicateM)+#if !MIN_VERSION_base(4,20,0) import           Data.List             (foldl')+#endif import           GHC.TypeLits          (KnownNat) import           Language.Haskell.TH 
src/Clash/Class/Exp.hs view
@@ -1,7 +1,8 @@ {-| Copyright  :  (C) 2019, Myrtle Software Ltd+                  2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qaylogic.com> -}  {-# LANGUAGE CPP #-}@@ -37,6 +38,8 @@     -- ^ Exponent     -> ExpResult a n     -- ^ Resized result, guaranteed to not have overflown++infixr 8 ^  instance KnownNat m => Exp (Index m) where   type ExpResult (Index m) n = Index (Max 2 (m ^ n))
src/Clash/Class/Num.hs view
@@ -1,5 +1,6 @@ {-| Copyright  :  (C) 2013-2016, University of Twente+                  2024,      Google LLC License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}@@ -42,6 +43,9 @@   -- that is potentially different from either argument.   mul :: a -> b -> MResult a b +infixl 7  `mul`+infixl 6  `add`, `sub`+ -- * Saturating arithmetic functions  -- | Determine how overflow and underflow are handled by the functions in@@ -76,19 +80,25 @@   satPred s n = satSub s n 1   {-# INLINE satPred #-} +infixl 7  `satMul`+infixl 6  `satAdd`, `satSub`+ -- | Addition that clips to 'maxBound' on overflow, and 'minBound' on underflow boundedAdd :: SaturatingNum a => a -> a -> a boundedAdd = satAdd SatBound {-# INLINE boundedAdd #-}+infixl 6  `boundedAdd`  -- | Subtraction that clips to 'maxBound' on overflow, and 'minBound' on -- underflow boundedSub  :: SaturatingNum a => a -> a -> a boundedSub = satSub SatBound {-# INLINE boundedSub #-}+infixl 6 `boundedSub`  -- | Multiplication that clips to 'maxBound' on overflow, and 'minBound' on -- underflow boundedMul :: SaturatingNum a => a -> a -> a boundedMul = satMul SatBound {-# INLINE boundedMul #-}+infixl 7  `boundedMul`
src/Clash/Class/Resize.hs view
@@ -1,6 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente                   2020,      Myrtle Software Ltd+                  2024,      QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -26,6 +27,8 @@ import GHC.Stack (HasCallStack) import GHC.TypeLits (Nat, KnownNat, type (+)) +import Clash.Sized.Internal (formatRange)+ -- | Coerce a value to be represented by a different number of bits class Resize (f :: Nat -> Type) where   -- | A sign-preserving resize operation@@ -61,9 +64,8 @@   if toInteger v > toInteger (maxBound @b)   || toInteger v < toInteger (minBound @b) then     error $ "Given integral " <> show (toInteger v) <> " is out of bounds for" <>-            " target type. Bounds of target type are: [" <>-            show (toInteger (minBound @b)) <> ".." <>-            show (toInteger (maxBound @b)) <> "]."+            " target type. Bounds of target type are: " <>+            formatRange (toInteger (minBound @b)) (toInteger (maxBound @b)) <> "."   else     () 
src/Clash/Examples.hs view
@@ -321,7 +321,7 @@       rx_busy       '.=' True       rx_sample_cnt '.=' 1       rx_cnt        '.=' 0-    -- Star of frame detected, Proceed with rest of data+    -- Start of frame detected, proceed with rest of data     'when' _rx_busy $ do       rx_sample_cnt '+=' 1       -- Logic to sample at middle of data
src/Clash/Explicit/BlockRam/Blob.hs view
@@ -1,5 +1,5 @@ {-|-Copyright  :  (C) 2021-2022, QBayLogic B.V.+Copyright  :  (C) 2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -236,55 +236,68 @@ -- See: https://github.com/clash-lang/clash-compiler/pull/2511 {-# CLASH_OPAQUE blockRamBlob# #-} --- | Create a 'MemBlob' binding from a list of values------ Since this uses Template Haskell, nothing in the arguments given to--- 'createMemBlob' can refer to something defined in the same module.------ === __Example__------ @--- 'createMemBlob' "content" 'Nothing' [15 :: Unsigned 8 .. 17]------ ram clk en = 'blockRamBlob' clk en content--- @------ The 'Data.Maybe.Maybe' datatype has don't care bits, where the actual value--- does not matter. But the bits need a defined value in the memory. Either 0 or--- 1 can be used, and both are valid representations of the data.------ >>> import qualified Prelude as P--- >>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]--- >>> :{--- createMemBlob "content0" (Just 0) es--- createMemBlob "content1" (Just 1) es--- x = 1--- :}------ >>> let pr = mapM_ (putStrLn . show)--- >>> pr $ P.map pack es--- 0b0_...._....--- 0b1_0000_0111--- 0b1_0000_1000--- >>> pr $ unpackMemBlob content0--- 0b0_0000_0000--- 0b1_0000_0111--- 0b1_0000_1000--- >>> pr $ unpackMemBlob content1--- 0b0_1111_1111--- 0b1_0000_0111--- 0b1_0000_1000--- >>> :{--- createMemBlob "contentN" Nothing es--- x = 1--- :}--- <BLANKLINE>--- <interactive>:...: error:...---     packBVs: cannot convert don't care values. Please specify a mapping to a definite value.------ Note how we hinted to @clashi@ that our multi-line command was a list of--- declarations by including a dummy declaration @x = 1@. Without this trick,--- @clashi@ would expect an expression and the Template Haskell would not work.+{- | Create a 'MemBlob' binding from a list of values++Since this uses Template Haskell, nothing in the arguments given to+'createMemBlob' can refer to something defined in the same module.++=== __Example__++@+'createMemBlob' "content" 'Nothing' [15 :: Unsigned 8 .. 17]++ram clk en = 'blockRamBlob' clk en content+@++The 'Data.Maybe.Maybe' datatype has don't care bits, where the actual value+does not matter. But the bits need a defined value in the memory. Either 0 or+1 can be used, and both are valid representations of the data.++>>> import qualified Prelude as P+>>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]+>>> :{+createMemBlob "content0" (Just 0) es+createMemBlob "content1" (Just 1) es+x = 1+:}++>>> let pr = mapM_ (putStrLn . show)+>>> pr $ P.map pack es+0b0_...._....+0b1_0000_0111+0b1_0000_1000+>>> pr $ unpackMemBlob content0+0b0_0000_0000+0b1_0000_0111+0b1_0000_1000+>>> pr $ unpackMemBlob content1+0b0_1111_1111+0b1_0000_0111+0b1_0000_1000++#if __GLASGOW_HASKELL__ >= 910+>>> :{+createMemBlob "contentN" Nothing es+x = 1+:}+<interactive>:...: error:...+    packBVs: cannot convert don't care values. Please specify a mapping to a definite value.+<BLANKLINE>++#else+>>> :{+createMemBlob "contentN" Nothing es+x = 1+:}+<BLANKLINE>+<interactive>:...: error:...+    packBVs: cannot convert don't care values. Please specify a mapping to a definite value.++#endif+Note how we hinted to @clashi@ that our multi-line command was a list of+declarations by including a dummy declaration @x = 1@. Without this trick,+@clashi@ would expect an expression and the Template Haskell would not work.+-} createMemBlob   :: forall a f    . ( Foldable f@@ -320,43 +333,55 @@   (len, runsB, endsB) = either error id packed   packed = packBVs care es --- | Create a 'MemBlob' from a list of values------ Since this uses Template Haskell, nothing in the arguments given to--- 'memBlobTH' can refer to something defined in the same module.------ === __Example__------ @--- ram clk en = 'blockRamBlob' clk en $(memBlobTH Nothing [15 :: Unsigned 8 .. 17])--- @------ The 'Data.Maybe.Maybe' datatype has don't care bits, where the actual value--- does not matter. But the bits need a defined value in the memory. Either 0 or--- 1 can be used, and both are valid representations of the data.------ >>> import qualified Prelude as P--- >>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]--- >>> content0 = $(memBlobTH (Just 0) es)--- >>> content1 = $(memBlobTH (Just 1) es)--- >>> let pr = mapM_ (putStrLn . show)--- >>> pr $ P.map pack es--- 0b0_...._....--- 0b1_0000_0111--- 0b1_0000_1000--- >>> pr $ unpackMemBlob content0--- 0b0_0000_0000--- 0b1_0000_0111--- 0b1_0000_1000--- >>> pr $ unpackMemBlob content1--- 0b0_1111_1111--- 0b1_0000_0111--- 0b1_0000_1000--- >>> $(memBlobTH Nothing es)--- <BLANKLINE>--- <interactive>:...: error:...---     • packBVs: cannot convert don't care values. Please specify a mapping to a definite value.---     • In the untyped splice: $(memBlobTH Nothing es)+{- | Create a 'MemBlob' from a list of values++Since this uses Template Haskell, nothing in the arguments given to+'memBlobTH' can refer to something defined in the same module.++=== __Example__++@+ram clk en = 'blockRamBlob' clk en $(memBlobTH Nothing [15 :: Unsigned 8 .. 17])+@++The 'Data.Maybe.Maybe' datatype has don't care bits, where the actual value+does not matter. But the bits need a defined value in the memory. Either 0 or+1 can be used, and both are valid representations of the data.++>>> import qualified Prelude as P+>>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]+>>> content0 = $(memBlobTH (Just 0) es)+>>> content1 = $(memBlobTH (Just 1) es)+>>> let pr = mapM_ (putStrLn . show)+>>> pr $ P.map pack es+0b0_...._....+0b1_0000_0111+0b1_0000_1000+>>> pr $ unpackMemBlob content0+0b0_0000_0000+0b1_0000_0111+0b1_0000_1000+>>> pr $ unpackMemBlob content1+0b0_1111_1111+0b1_0000_0111+0b1_0000_1000++#if __GLASGOW_HASKELL__ >= 910+>>> $(memBlobTH Nothing es)+<interactive>:...: error:...+    • packBVs: cannot convert don't care values. Please specify a mapping to a definite value.+    • In the untyped splice: $(memBlobTH Nothing es)+<BLANKLINE>++#else+>>> $(memBlobTH Nothing es)+<BLANKLINE>+<interactive>:...: error:...+    • packBVs: cannot convert don't care values. Please specify a mapping to a definite value.+    • In the untyped splice: $(memBlobTH Nothing es)++#endif+-} memBlobTH   :: forall a f    . ( Foldable f
src/Clash/Explicit/BlockRam/File.hs view
@@ -11,26 +11,22 @@ Block RAM primitives that can be initialized with a data file. The BNF grammar for this data file is simple: -@-FILE = LINE+-LINE = BIT+-BIT  = '0'-     | '1'-@+> FILE = LINE++> LINE = BIT++> BIT  = '0'+>      | '1'  Consecutive @LINE@s correspond to consecutive memory addresses starting at @0@. For example, a data file @memory.bin@ containing the 9-bit unsigned numbers @7@ to @13@ looks like: -@-000000111-000001000-000001001-000001010-000001011-000001100-000001101-@+> 000000111+> 000001000+> 000001001+> 000001010+> 000001011+> 000001100+> 000001101  Such a file can be produced with 'memFile': 
src/Clash/Explicit/BlockRam/Internal.hs view
@@ -1,9 +1,10 @@ {-|-Copyright  :  (C) 2021-2022, QBayLogic B.V.+Copyright  :  (C) 2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -} +{-# LANGUAGE CPP #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE Trustworthy #-}@@ -17,7 +18,9 @@ import qualified Data.ByteString.Lazy as L import Data.ByteString.Builder (Builder, toLazyByteString, word8, word64BE) import qualified Data.ByteString.Unsafe as B+#if !MIN_VERSION_base(4,20,0) import Data.Foldable (foldl')+#endif import Data.Word (Word64) import GHC.Exts (Addr#) import GHC.TypeLits (KnownNat, Nat)
src/Clash/Explicit/ROM/File.hs view
@@ -10,26 +10,22 @@  ROMs initialized with a data file. The BNF grammar for this data file is simple: -@-FILE = LINE+-LINE = BIT+-BIT  = '0'-     | '1'-@+> FILE = LINE++> LINE = BIT++> BIT  = '0'+>      | '1'  Consecutive @LINE@s correspond to consecutive memory addresses starting at @0@. For example, a data file @memory.bin@ containing the 9-bit unsigned numbers @7@ to @13@ looks like: -@-000000111-000001000-000001001-000001010-000001011-000001100-000001101-@+> 000000111+> 000001000+> 000001001+> 000001010+> 000001011+> 000001100+> 000001101  Such a file can be produced with 'memFile': 
src/Clash/Explicit/Reset.hs view
@@ -184,36 +184,32 @@ -- === __Implementation details__ -- 'resetSynchronizer' implements the following circuit for asynchronous domains: ----- @---                                   rst---   --------------------------------------+---                       |                 |---                  +----v----+       +----v----+---     deasserted   |         |       |         |---   --------------->         +------->         +-------->---                  |         |       |         |---              +---|>        |   +---|>        |---              |   |         |   |   |         |---              |   +---------+   |   +---------+---      clk     |                 |---   -----------------------------+--- @+-- >                                   rst+-- >   --------------------------------------++-- >                       |                 |+-- >                  +----v----+       +----v----++-- >     deasserted   |         |       |         |+-- >   --------------->         +------->         +-------->+-- >                  |         |       |         |+-- >              +---|>        |   +---|>        |+-- >              |   |         |   |   |         |+-- >              |   +---------+   |   +---------++-- >      clk     |                 |+-- >   -----------------------------+ -- -- This corresponds to figure 3d at <https://www.embedded.com/asynchronous-reset-synchronization-and-distribution-challenges-and-solutions/> -- -- For synchronous domains two sequential dflipflops are used: ----- @---                  +---------+       +---------+---     rst          |         |       |         |---   --------------->         +------->         +-------->---                  |         |       |         |---              +---|>        |   +---|>        |---              |   |         |   |   |         |---              |   +---------+   |   +---------+---      clk     |                 |---   -----------------------------+--- @+-- >                  +---------+       +---------++-- >     rst          |         |       |         |+-- >   --------------->         +------->         +-------->+-- >                  |         |       |         |+-- >              +---|>        |   +---|>        |+-- >              |   |         |   |   |         |+-- >              |   +---------+   |   +---------++-- >      clk     |                 |+-- >   -----------------------------+ -- resetSynchronizer   :: forall dom
src/Clash/Explicit/Signal.hs view
@@ -27,7 +27,7 @@   { _name:: 'GHC.TypeLits.Symbol'   -- ^ Domain name   , _period :: 'GHC.TypeLits.Nat'-  -- ^ Clock period in /ps/+  -- ^ Clock period in \/ps\/   , _edge :: 'ActiveEdge'   -- ^ Active edge of the clock   , _reset :: 'ResetKind'@@ -46,8 +46,8 @@ configured as follows:  @-instance KnownDomain "System" where-  type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+instance KnownDomain 'System' where+  type KnownConf 'System' = 'DomainConfiguration 'System' 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh   knownDomain = 'SDomainConfiguration' SSymbol SNat 'SRising' 'SAsynchronous' 'SDefined' 'SActiveHigh' @ @@ -514,7 +514,7 @@ -- cannot be done precisely and can lead to odd behavior. For example, -- -- @--- sample $ unsafeSynchronizer @Dom2 @Dom7 . unsafeSynchronizer @Dom7 @Dom2 $ fromList [0..10]+-- sample $ unsafeSynchronizer \@Dom2 \@Dom7 . unsafeSynchronizer \@Dom7 \@Dom2 $ fromList [0..10] -- > [0,4,4,4,7,7,7,7,11,11,11.. -- @ --@@ -917,9 +917,7 @@ -- -- It prints a message of the form ----- @--- Signal sampled for N cycles until value X--- @+-- > Signal sampled for N cycles until value X -- -- __NB__: This function is not synthesizable --
src/Clash/Explicit/Testbench.hs view
@@ -449,8 +449,8 @@ --   where --     testInput      = pure ((1 :> 2 :> 3 :> Nil) :> (4 :> 5 :> 6 :> Nil) :> Nil) --     expectedOutput = outputVerifier' ((1:>2:>3:>4:>5:>6:>Nil):>Nil)---     done           = exposeClockResetEnable (expectedOutput (topEntity <$> testInput)) clk rst---     clk            = 'tbSystemClockGen' (not <\$\> done)+--     done           = exposeClockResetEnable (expectedOutput (topEntity \<\$> testInput)) clk rst+--     clk            = 'tbSystemClockGen' (not \<\$> done) --     rst            = systemResetGen -- @ tbSystemClockGen
src/Clash/Explicit/Verification.hs view
@@ -84,26 +84,22 @@  -- | Truth table for 'not': ----- @--- a     | not a--- --------------- True  | False--- False | True--- @+-- > a     | not a+-- > ------------+-- > True  | False+-- > False | True not :: AssertionValue dom a => a -> Assertion dom not (toAssertionValue -> a) = Assertion (isTemporal a) (CvNot (assertion a)) {-# INLINE not #-}  -- | Truth table for 'and': ----- @--- a     | b     | a `and` b--- --------------|------------- False | False | False--- False | True  | False--- True  | False | False--- True  | True  | True--- @+-- > a     | b     | a `and` b+-- > --------------|----------+-- > False | False | False+-- > False | True  | False+-- > True  | False | False+-- > True  | True  | True and :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom and (toAssertionValue -> a) (toAssertionValue -> b) =   Assertion@@ -113,14 +109,12 @@  -- | Truth table for 'or': ----- @--- a     | b     | a `or` b--- --------------|------------ False | False | False--- False | True  | True--- True  | False | True--- True  | True  | True--- @+-- > a     | b     | a `or` b+-- > --------------|---------+-- > False | False | False+-- > False | True  | True+-- > True  | False | True+-- > True  | True  | True or :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom or (toAssertionValue -> a) (toAssertionValue -> b) =   Assertion@@ -131,14 +125,12 @@ -- | -- Truth table for 'implies': ----- @--- a     | b     | a `implies` b--- --------------|----------------- False | False | True--- False | True  | True--- True  | False | False--- True  | True  | True--- @+-- > a     | b     | a `implies` b+-- > --------------|--------------+-- > False | False | True+-- > False | True  | True+-- > True  | False | False+-- > True  | True  | True implies :: (AssertionValue dom a, AssertionValue dom b) => a -> b -> Assertion dom implies (toAssertionValue -> Assertion aTmp a) (toAssertionValue -> Assertion bTmp b) =   Assertion (max aTmp bTmp) (CvImplies a b)@@ -146,14 +138,12 @@  -- | Truth table for 'next': ----- @--- a[n]  | a[n+1] | a `implies` next a--- ---------------|---------------------- False | False  | True--- False | True   | True--- True  | False  | False--- True  | True   | True--- @+-- > a[n]  | a[n+1] | a `implies` next a+-- > ---------------|-------------------+-- > False | False  | True+-- > False | True   | True+-- > True  | False  | False+-- > True  | True   | True -- -- where a[n] represents the value of @a@ at cycle @n@ and @a[n+1]@ represents -- the value of @a@ at cycle @n+1@. Cycle n is an arbitrary cycle.@@ -163,14 +153,12 @@  -- | Truth table for 'nextN': ----- @--- a[n]  | a[n+m] | a `implies` next m a--- ---------------|------------------------ False | False  | True--- False | True   | True--- True  | False  | False--- True  | True   | True--- @+-- > a[n]  | a[n+m] | a `implies` next m a+-- > ---------------|---------------------+-- > False | False  | True+-- > False | True   | True+-- > True  | False  | False+-- > True  | True   | True -- -- where a[n] represents the value of @a@ at cycle @n@ and a[n+m] represents -- the value of @a@ at cycle @n+m@. Cycle n is an arbitrary cycle.
src/Clash/Intel/ClockGen.hs view
@@ -193,26 +193,22 @@ the wrong type, the GHC compiler will complain about satisfying @NumOutClocks@. The error message on GHC 9.4 and up is: -@-    • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks-                        (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst-                           ([...])-                           DomInput) <= 18-    • In the expression: alteraPllSync clkIn rstIn-@+>     • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+>                         (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+>                            ([...])+>                            DomInput) <= 18+>     • In the expression: alteraPllSync clkIn rstIn  On older GHC versions, the error message is: -@-    • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks-                             (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst-                                ([...])-                                DomInput)-                           <=? 18’-                     with ‘'True’-        arising from a use of ‘alteraPllSync’-    • In the expression: alteraPllSync clkIn rstIn-@+>     • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+>                              (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+>                                 ([...])+>                                 DomInput)+>                            <=? 18’+>                      with ‘'True’+>         arising from a use of ‘alteraPllSync’+>     • In the expression: alteraPllSync clkIn rstIn  The above error message is also emitted when trying to instantiate more than 18 output clocks, as it will fail to find an instance. As 'altpllSync' supports no@@ -220,18 +216,14 @@ also cause a type checking error. On GHC 9.4 and up, the error for attempting to instantiate 6 clocks is: -@-    • Cannot satisfy: 6 <= 5-    • In the expression: altpllSync clkIn rstIn-@+>     • Cannot satisfy: 6 <= 5+>     • In the expression: altpllSync clkIn rstIn  On older GHC versions, the error message is less clear: -@-    • Couldn't match type ‘'False’ with ‘'True’-        arising from a use of ‘altpllSync’-    • In the expression: altpllSync clkIn rstIn-@+>     • Couldn't match type ‘'False’ with ‘'True’+>         arising from a use of ‘altpllSync’+>     • In the expression: altpllSync clkIn rstIn -}  {- $unsafe
src/Clash/Magic.hs view
@@ -44,6 +44,7 @@   ) where  import Data.String.Interpolate     (__i)+import GHC.Magic                   (noinline) import GHC.Stack                   (HasCallStack, withFrozenCallStack) import Clash.NamedTypes            ((:::)) import GHC.TypeLits                (Nat,Symbol)@@ -259,7 +260,8 @@  -- | 'True' in Haskell/Clash simulation. Replaced by 'False' when generating HDL. clashSimulation :: Bool-clashSimulation = True+clashSimulation = noinline True+-- The 'noinline' is here to prevent SpecConstr from poking through the OPAQUE, see #2736 -- See: https://github.com/clash-lang/clash-compiler/pull/2511 {-# CLASH_OPAQUE clashSimulation #-} 
src/Clash/Prelude/BlockRam/File.hs view
@@ -11,26 +11,22 @@ Block RAM primitives that can be initialized with a data file. The BNF grammar for this data file is simple: -@-FILE = LINE+-LINE = BIT+-BIT  = '0'-     | '1'-@+> FILE = LINE++> LINE = BIT++> BIT  = '0'+>      | '1'  Consecutive @LINE@s correspond to consecutive memory addresses starting at @0@. For example, a data file @memory.bin@ containing the 9-bit unsigned numbers @7@ to @13@ looks like: -@-000000111-000001000-000001001-000001010-000001011-000001100-000001101-@+> 000000111+> 000001000+> 000001001+> 000001010+> 000001011+> 000001100+> 000001101  Such a file can be produced with 'E.memFile': 
src/Clash/Prelude/DataFlow.hs view
@@ -75,11 +75,11 @@ newtype DataFlow' dom iEn oEn i o   = DF   { df :: 'Signal' dom i     -- Incoming data-       -> 'Signal' dom iEn   -- Flagged with /valid/ bits @iEn@.-       -> 'Signal' dom oEn   -- Incoming back-pressure, /ready/ edge.+       -> 'Signal' dom iEn   -- Flagged with \/valid\/ bits \@iEn\@.+       -> 'Signal' dom oEn   -- Incoming back-pressure, \/ready\/ edge.        -> ( 'Signal' dom o   -- Outgoing data.-          , 'Signal' dom oEn -- Flagged with /valid/ bits @oEn@.-          , 'Signal' dom iEn -- Outgoing back-pressure, /ready/ edge.+          , 'Signal' dom oEn -- Flagged with \/valid\/ bits \@oEn\@.+          , 'Signal' dom iEn -- Outgoing back-pressure, \/ready\/ edge.           )   } @@@ -122,11 +122,11 @@ -- -- @ -- 'Signal' dom i        -- Incoming data.--- -> 'Signal' dom Bool  -- Flagged with a single /valid/ bit.--- -> 'Signal' dom Bool  -- Incoming back-pressure, /ready/ bit.+-- -> 'Signal' dom Bool  -- Flagged with a single \/valid\/ bit.+-- -> 'Signal' dom Bool  -- Incoming back-pressure, \/ready\/ bit. -- -> ( 'Signal' dom o   -- Outgoing data.---    , 'Signal' dom oEn -- Flagged with a single /valid/ bit.---    , 'Signal' dom iEn -- Outgoing back-pressure, /ready/ bit.+--    , 'Signal' dom oEn -- Flagged with a single \/valid\/ bit.+--    , 'Signal' dom iEn -- Outgoing back-pressure, \/ready\/ bit. --    ) -- @ --
src/Clash/Prelude/ROM/File.hs view
@@ -10,26 +10,22 @@  ROMs initialized with a data file. The BNF grammar for this data file is simple: -@-FILE = LINE+-LINE = BIT+-BIT  = '0'-     | '1'-@+> FILE = LINE++> LINE = BIT++> BIT  = '0'+>      | '1'  Consecutive @LINE@s correspond to consecutive memory addresses starting at @0@. For example, a data file @memory.bin@ containing the 9-bit unsigned numbers @7@ to @13@ looks like: -@-000000111-000001000-000001001-000001010-000001011-000001100-000001101-@+> 000000111+> 000001000+> 000001001+> 000001010+> 000001011+> 000001100+> 000001101  Such a file can be produced with 'memFile': 
src/Clash/Promoted/Nat.hs view
@@ -536,7 +536,7 @@ -- head :: Vec (n + 1) a -> a -- -- head' :: forall n a. (1 'GHC.TypeNats.<=' n) => Vec n a -> a--- head' = 'leToPlus' @1 @n head+-- head' = 'leToPlus' \@1 \@n head -- @ leToPlus   :: forall (k :: Nat) (n :: Nat) r
src/Clash/Signal.hs view
@@ -26,7 +26,7 @@   { _name :: 'Domain'   -- ^ Domain name   , _period :: 'Clash.Promoted.Nat.Nat'-  -- ^ Clock period in /ps/+  -- ^ Clock period in \/ps\/   , _activeEdge :: 'ActiveEdge'   -- ^ Active edge of the clock   , _resetKind :: 'ResetKind'@@ -45,8 +45,8 @@ chosen:  @-instance KnownDomain "System" where-  type KnownConf "System" = 'DomainConfiguration "System" 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh+instance KnownDomain 'System' where+  type KnownConf 'System' = 'DomainConfiguration 'System' 10000 'Rising 'Asynchronous 'Defined 'ActiveHigh   knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh @ @@ -2173,9 +2173,7 @@ -- -- It prints a message of the form ----- @--- Signal sampled for N cycles until value X--- @+-- > Signal sampled for N cycles until value X -- -- __NB__: This function is not synthesizable --
src/Clash/Signal/BiSignal.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2017, Google Inc.                   2019, Myrtle Software Ltd-                  2022-2023, QBayLogic B.V.+                  2022-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -77,7 +77,7 @@ g clk rst en s = writeToBiSignal s (mealy clk rst en counter (True, 0) (readFromBiSignal s))  --- | Connect the /f/ and /g/ circuits to the same bus+-- | Connect the \/f\/ and \/g\/ circuits to the same bus topEntity   :: Clock System   -> Reset System@@ -133,8 +133,8 @@ import           GHC.Stack                  (HasCallStack) import           Data.Reflection            (Given (..)) --- | Used to specify the /default/ behavior of a \"BiSignal\", i.e. what value is--- read when no value is being written to it.+-- | Used to specify the /default/ behavior of a \"BiSignal\" in Haskell simulation, i.e.+-- what value is read when no value is being written to it. data BiSignalDefault   = PullUp   -- ^ __inout__ port behaves as if connected to a pull-up resistor@@ -277,8 +277,7 @@   -> Signal d Bool   -> Signal d (BitVector n)   -> BiSignalOut ds d n--- writeToBiSignal# = writeToBiSignal#-writeToBiSignal# _ maybeSignal _ _ = BiSignalOut [maybeSignal]+writeToBiSignal# bIn maybeSignal wEn val = BiSignalOut [bIn `seq` wEn `seq` val `seq` maybeSignal] -- See: https://github.com/clash-lang/clash-compiler/pull/2511 {-# CLASH_OPAQUE writeToBiSignal# #-} {-# ANN writeToBiSignal# hasBlackBox #-}
src/Clash/Signal/Bundle.hs view
@@ -82,10 +82,10 @@ --   type Unbundled dom (Pair a b) = Pair (Signal dom a) (Signal dom b) -- --   -- bundle :: Pair (Signal dom a) (Signal dom b) -> Signal dom (Pair a b)---   bundle   (MkPair as bs) = MkPair <$> as <*> bs+--   bundle   (MkPair as bs) = MkPair '<$>' as '<*>' bs -- --   -- unbundle :: Signal dom (Pair a b) -> Pair (Signal dom a) (Signal dom b)---   unbundle pairs = MkPair (getA <$> pairs) (getB <$> pairs)+--   unbundle pairs = MkPair (getA '<$>' pairs) (getB '<$>' pairs) -- @  class Bundle a where
src/Clash/Signal/Bundle/Internal.hs view
@@ -1,3 +1,9 @@+{-|+Copyright  :  (C) 2024, QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>+-}+ {-# LANGUAGE CPP #-} {-# LANGUAGE QuasiQuotes #-} {-# LANGUAGE TemplateHaskell #-}@@ -9,7 +15,10 @@ import           Clash.CPP                   (maxTupleSize) import           Clash.Signal.Internal       (Signal((:-))) import           Clash.XException            (seqX)-import           Data.List                   (foldl', uncons)+#if !MIN_VERSION_base(4,20,0)+import           Data.List                   (foldl')+#endif+import           Data.List                   (uncons) import           Data.String.Interpolate     (__i) import qualified Language.Haskell.TH.Syntax  as TH import           Language.Haskell.TH
src/Clash/Signal/Trace.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2018, Google Inc.                   2019, Myrtle Software Ltd-                  2022, QBayLogic B.V.+                  2022-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -111,7 +111,10 @@ import           Data.Char             (ord, chr) import           Data.IORef   (IORef, atomicModifyIORef', atomicWriteIORef, newIORef, readIORef)-import           Data.List             (foldl1', foldl', unzip4, transpose, uncons)+#if !MIN_VERSION_base(4,20,0)+import           Data.List             (foldl')+#endif+import           Data.List             (foldl1', unzip4, transpose, uncons) import qualified Data.Map.Strict       as Map import           Data.Maybe            (fromMaybe, catMaybes) import qualified Data.Text             as Text
src/Clash/Sized/BitVector.hs view
@@ -1,11 +1,12 @@ {-| Copyright  :  (C) 2013-2016, University of Twente-                  2022     , Google Inc.+                  2022-2024, Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}  {-# LANGUAGE Trustworthy #-}+{-# LANGUAGE TypeFamilies #-}  {-# OPTIONS_HADDOCK show-extensions #-} @@ -37,7 +38,7 @@ where  import Clash.Sized.Internal.BitVector-import Clash.Promoted.Nat (natToNum)+import Clash.Promoted.Nat (SNat(..), SNatLE(..), compareSNat, natToNum) import Data.Bits (shiftL, shiftR) import GHC.TypeNats (KnownNat) @@ -55,7 +56,9 @@ -- 0b0111_1000 -- (+>>.) :: forall n. KnownNat n => Bit -> BitVector n -> BitVector n-b +>>. bv = replaceBit# (shiftR bv 1) (natToNum @n - 1) b+b +>>. bv = case compareSNat (SNat @n) (SNat @0) of+  SNatGT -> replaceBit# (shiftR bv 1) (natToNum @n - 1) b+  SNatLE -> bv  infixr 4 .<<+ -- | Shift in a bit from the LSB side of a 'BitVector'. Equal to left shifting@@ -67,4 +70,6 @@ -- 0b1110_0001 -- (.<<+) :: forall n. KnownNat n => BitVector n -> Bit -> BitVector n-bv .<<+ b = replaceBit# (shiftL bv 1) 0 b+bv .<<+ b = case compareSNat (SNat @n) (SNat @0) of+  SNatGT -> replaceBit# (shiftL bv 1) 0 b+  SNatLE -> bv
src/Clash/Sized/Fixed.hs view
@@ -743,10 +743,8 @@ -- synthesizable function like 'Clash.Prelude.ROM.File.asyncRomFile'. For -- example, consider a file @Data.txt@ containing: ----- @--- 1.2 2.0 3.0 4.0--- -1.0 -2.0 -3.5 -4.0--- @+-- > 1.2 2.0 3.0 4.0+-- > -1.0 -2.0 -3.5 -4.0 -- -- which we want to put in a ROM, interpreting them as @8.8@ signed fixed point -- numbers. What we do is that we first create a conversion utility,@@ -786,30 +784,24 @@ -- -- We then compile this to an executable: ----- @--- \$ clash --make createRomFile.hs--- @+-- > $ clash --make createRomFile.hs -- -- We can then use this utility to convert our @Data.txt@ file which contains -- 'Double's to a @Data.bin@ file which will containing the desired ASCII-encoded -- binary data: ----- @--- \$ ./createRomFile \"Data.txt\" \"Data.bin\"--- @+-- > $ ./createRomFile Data.txt Data.bin -- -- Which results in a @Data.bin@ file containing: ----- @--- 0000000100110011--- 0000001000000000--- 0000001100000000--- 0000010000000000--- 1111111100000000--- 1111111000000000--- 1111110010000000--- 1111110000000000--- @+-- > 0000000100110011+-- > 0000001000000000+-- > 0000001100000000+-- > 0000010000000000+-- > 1111111100000000+-- > 1111111000000000+-- > 1111110010000000+-- > 1111110000000000 -- -- We can then use this @Data.bin@ file in for our ROM: --
+ src/Clash/Sized/Internal.hs view
@@ -0,0 +1,24 @@+{-|+Copyright  :  (C) 2024     , QBayLogic B.V.+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>+-}++module Clash.Sized.Internal where++-- | Format a range of numbers for use in error messages+--+-- If the upper bound is below the lower bound, @"\<empty range\>"@ is returned.+-- If the bounds are equal, @"[n]"@ is returned (for bounds equal to /n/).+-- Otherwise, @formatRange n m@ returns @"[n..m]"@.+formatRange ::+  (Ord a, Show a) =>+  -- | Lower bound+  a ->+  -- | Upper bound+  a ->+  String+formatRange n m+  | m < n     = "<empty range>"+  | m == n    = '[' : shows n "]"+  | otherwise = '[' : show n ++ ".." ++ shows m "]"
src/Clash/Sized/Internal/BitVector.hs view
@@ -2,7 +2,7 @@ Copyright  :  (C) 2013-2016, University of Twente,                   2019     , Gergő Érdi                   2016-2019, Myrtle Software Ltd,-                  2021-2022, QBayLogic B.V.+                  2021-2024, QBayLogic B.V.                   2023     , Nadia Chambers License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>@@ -131,10 +131,12 @@   , undefError   , checkUnpackUndef   , bitPattern+  , xToBV   ) where  import Control.DeepSeq            (NFData (..))+import Control.Exception          (catch, evaluate) import Control.Lens               (Index, Ixed (..), IxValue) import Data.Bits                  (Bits (..), FiniteBits (..)) import Data.Data                  (Data)@@ -148,20 +150,19 @@ import GHC.Exts   (Word#, Word (W#), eqWord#, int2Word#, isTrue#, uncheckedShiftRL#) #if MIN_VERSION_base(4,15,0)-import GHC.Exts (minusWord#, gtWord#, word2Int#)+import GHC.Exts (minusWord#, gtWord#, word2Int#, dataToTag#) import GHC.Num.BigNat (bigNatShiftR#, bigNatToWord) import GHC.Num.Integer (integerFromNatural, integerToNatural) import GHC.Num.Natural   (Natural (..), naturalFromWord, naturalShiftL, naturalShiftR, naturalToWord) #else-import GHC.Exts ((>#))+import GHC.Exts ((>#), dataToTag#) import qualified GHC.Exts import GHC.Integer.GMP.Internals  (Integer (..), bigNatToWord, shiftRBigNat) import GHC.Natural   (Natural (..), naturalFromInteger, wordToNatural) #endif import GHC.Natural                (naturalToInteger)-import GHC.Prim                   (dataToTag#) import GHC.Stack                  (withFrozenCallStack) import GHC.TypeLits               (KnownNat, Nat, type (+), type (-)) #if MIN_VERSION_base(4,15,0)@@ -183,6 +184,7 @@ #else import Language.Haskell.TH        (TypeQ) #endif+import System.IO.Unsafe               (unsafeDupablePerformIO) import Test.QuickCheck.Arbitrary  (Arbitrary (..), CoArbitrary (..),                                    arbitraryBoundedIntegral,                                    coarbitraryIntegral, shrinkIntegral)@@ -193,8 +195,9 @@ import Clash.Class.Resize         (Resize (..)) import Clash.Promoted.Nat   (SNat (..), SNatLE (..), compareSNat, snatToInteger, snatToNum, natToNum)+import Clash.Sized.Internal (formatRange) import Clash.XException-  (ShowX (..), NFDataX (..), errorX, isX, showsPrecXWith, rwhnfX)+  (ShowX (..), NFDataX (..), errorX, isX, showsPrecXWith, rwhnfX, XException(..))  import Clash.Sized.Internal.Mod @@ -506,6 +509,7 @@   deepErrorX _ = undefined#   rnfX = rwhnfX   hasUndefined bv = isLeft (isX bv) || unsafeMask bv /= 0+  ensureSpine = xToBV -- Converts `XException` to 'undefined#'  -- | Create a binary literal --@@ -1049,9 +1053,8 @@ #endif     err = error $ concat [ "(!): "                          , show i-                         , " is out of range ["-                         , show (sz - 1)-                         , "..0]"+                         , " is out of range "+                         , formatRange 0 (sz - 1)                          ]  -- See: https://github.com/clash-lang/clash-compiler/pull/2511@@ -1142,9 +1145,8 @@ #endif     err  = error $ concat [ "replaceBit: "                           , show i-                          , " is out of range ["-                          , show (sz - 1)-                          , "..0]"+                          , " is out of range "+                          , formatRange 0 (sz - 1)                           ]  -- See: https://github.com/clash-lang/clash-compiler/pull/2511@@ -1605,3 +1607,11 @@       | otherwise = error $         "Invalid bit pattern: " ++ show c ++         ", expecting one of '0', '1', '.', '_', or a lowercase alphabetic character"++xToBV :: KnownNat n => BitVector n -> BitVector n+xToBV x =+  unsafeDupablePerformIO (catch (evaluate x)+                                (\(XException _) -> return undefined#))+-- See: https://github.com/clash-lang/clash-compiler/pull/2511+{-# CLASH_OPAQUE xToBV #-}+{-# ANN xToBV hasBlackBox #-}
src/Clash/Sized/Internal/Index.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2019, Myrtle Software Ltd,-                  2021-2023, QBayLogic B.V.+                  2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -108,6 +108,7 @@ import Clash.Class.Parity         (Parity (..)) import Clash.Class.Resize         (Resize (..)) import Clash.Class.BitPack.BitIndex (replaceBit)+import Clash.Sized.Internal       (formatRange) import {-# SOURCE #-} Clash.Sized.Internal.BitVector (BitVector (BV), high, low, undefError) import qualified Clash.Sized.Internal.BitVector as BV import Clash.Promoted.Nat         (SNat(..), snatToNum, natToInteger, leToPlusKN)@@ -347,7 +348,7 @@   where     bound = natToInteger @n     err   = errorX ("Clash.Sized.Index: result " ++ show i ++-                   " is out of bounds: [0.." ++ show (bound - 1) ++ "]")+                   " is out of bounds: " ++ formatRange 0 (bound - 1))  instance ExtendingNum (Index m) (Index n) where   type AResult (Index m) (Index n) = Index (m + n - 1)@@ -591,5 +592,5 @@   range (a, b) = [a..b]   index ab@(a, b) x     | inRange ab x = fromIntegral $ x - a-    | otherwise = error $ printf "Index %d out of bounds (%d, %d)" x a b+    | otherwise = error $ printf "Index (%d) out of range ((%d, %d))" x a b   inRange (a, b) x = a <= x && x <= b
src/Clash/Sized/Internal/Signed.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016     , Myrtle Software Ltd,-                  2021-2023, QBayLogic B.V.+                  2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -881,7 +881,7 @@   range (a, b) = [a..b]   index ab@(a, b) x     | inRange ab x = fromIntegral $ x - a-    | otherwise = error $ printf "Index %d out of bounds (%d, %d) ab" x a b+    | otherwise = error $ printf "Index (%d) out of range ((%d, %d))" x a b   inRange (a, b) x = a <= x && x <= b  -- | Shift left that ties to zero on negative shifts
src/Clash/Sized/Internal/Unsigned.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016     , Myrtle Software Ltd,-                  2021-2023, QBayLogic B.V.+                  2021-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -794,7 +794,7 @@   range (a, b) = [a..b]   index ab@(a, b) x     | inRange ab x = fromIntegral $ x - a-    | otherwise = error $ printf "Index %d out of bounds (%d, %d) ab" x a b+    | otherwise = error $ printf "Index (%d) out of range ((%d, %d))" x a b   inRange (a, b) x = a <= x && x <= b  unsignedToWord :: Unsigned WORD_SIZE_IN_BITS -> Word
src/Clash/Sized/RTree.hs view
@@ -1,6 +1,6 @@ {-| Copyright  :  (C) 2016, University of Twente-                  2022, QBayLogic B.V.+                  2022-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -298,7 +298,31 @@ defined in the instance 'Clash.Class.Num.ExtendingNum' instance of 'Index'. However, we cannot simply use 'Clash.Sized.Vector.fold' to create a tree-structure of 'Clash.Class.Num.add's:-#if __GLASGOW_HASKELL__ >= 900++#if __GLASGOW_HASKELL__ >= 910+>>> :{+let populationCount' :: (KnownNat (2^d), KnownNat d, KnownNat (2^d+1))+                     => BitVector (2^d) -> Index (2^d+1)+    populationCount' = tfold (resize . bv2i . pack) add . v2t . bv2v+:}+<interactive>:...+    • Couldn't match type: (((2 ^ d) + 1) + ((2 ^ d) + 1)) - 1+                     with: (2 ^ d) + 1+      Expected: Index ((2 ^ d) + 1)+                -> Index ((2 ^ d) + 1) -> Index ((2 ^ d) + 1)+        Actual: Index ((2 ^ d) + 1)+                -> Index ((2 ^ d) + 1)+                -> AResult (Index ((2 ^ d) + 1)) (Index ((2 ^ d) + 1))+    • In the second argument of ‘tfold’, namely ‘add’+      In the first argument of ‘(.)’, namely+        ‘tfold (resize . bv2i . pack) add’+      In the expression: tfold (resize . bv2i . pack) add . v2t . bv2v+    • Relevant bindings include+        populationCount' :: BitVector (2 ^ d) -> Index ((2 ^ d) + 1)+          (bound at ...)+<BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900 >>> :{ let populationCount' :: (KnownNat (2^d), KnownNat d, KnownNat (2^d+1))                      => BitVector (2^d) -> Index (2^d+1)
src/Clash/Sized/Vector.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2017     , Myrtle Software Ltd-                  2022-2023, QBayLogic B.V.+                  2022-2024, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> -}@@ -408,9 +408,20 @@ >>> head (1:>2:>3:>Nil) 1 -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 910 >>> head Nil+<interactive>:...+    • Couldn't match type ‘1’ with ‘0’+      Expected: Vec (0 + 1) a+        Actual: Vec 0 a+    • In the first argument of ‘head’, namely ‘Nil’+      In the expression: head Nil+      In an equation for ‘it’: it = head Nil <BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900+>>> head Nil+<BLANKLINE> <interactive>:...     • Couldn't match type ‘1’ with ‘0’       Expected: Vec (0 + 1) a@@ -443,9 +454,20 @@ >>> tail (1:>2:>3:>Nil) 2 :> 3 :> Nil -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 910 >>> tail Nil+<interactive>:...+    • Couldn't match type ‘1’ with ‘0’+      Expected: Vec (0 + 1) a+        Actual: Vec 0 a+    • In the first argument of ‘tail’, namely ‘Nil’+      In the expression: tail Nil+      In an equation for ‘it’: it = tail Nil <BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900+>>> tail Nil+<BLANKLINE> <interactive>:...     • Couldn't match type ‘1’ with ‘0’       Expected: Vec (0 + 1) a@@ -478,9 +500,20 @@ >>> last (1:>2:>3:>Nil) 3 -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 910 >>> last Nil+<interactive>:...+    • Couldn't match type ‘1’ with ‘0’+      Expected: Vec (0 + 1) a+        Actual: Vec 0 a+    • In the first argument of ‘last’, namely ‘Nil’+      In the expression: last Nil+      In an equation for ‘it’: it = last Nil <BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900+>>> last Nil+<BLANKLINE> <interactive>:...     • Couldn't match type ‘1’ with ‘0’       Expected: Vec (0 + 1) a@@ -514,9 +547,20 @@ >>> init (1:>2:>3:>Nil) 1 :> 2 :> Nil -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 910 >>> init Nil+<interactive>:...+    • Couldn't match type ‘1’ with ‘0’+      Expected: Vec (0 + 1) a+        Actual: Vec 0 a+    • In the first argument of ‘init’, namely ‘Nil’+      In the expression: init Nil+      In an equation for ‘it’: it = init Nil <BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900+>>> init Nil+<BLANKLINE> <interactive>:...     • Couldn't match type ‘1’ with ‘0’       Expected: Vec (0 + 1) a@@ -809,7 +853,7 @@  {- | Zip two vectors with a functions that also takes the elements' indices. -#if __GLASGOW_HASKELL__ >= 900 && __GLASGOW_HASKELL__ < 904+#if (__GLASGOW_HASKELL__ >= 900 && __GLASGOW_HASKELL__ < 904) || __GLASGOW_HASKELL__ >= 910 >>> izipWith (\i a b -> i + a + b) (2 :> 2 :> Nil)  (3 :> 3:> Nil) *** Exception: X: Clash.Sized.Index: result 2 is out of bounds: [0..1] ...@@ -1490,9 +1534,21 @@ >>> take d0               (1:>2:>Nil) Nil -#if __GLASGOW_HASKELL__ == 906+#if __GLASGOW_HASKELL__ >= 910 >>> take d4               (1:>2:>Nil)+<interactive>:...+    • Couldn't match type ‘4 + n0’ with ‘2’+      Expected: Vec (4 + n0) a+        Actual: Vec (1 + 1) a+      The type variable ‘n0’ is ambiguous+    • In the second argument of ‘take’, namely ‘(1 :> 2 :> Nil)’+      In the expression: take d4 (1 :> 2 :> Nil)+      In an equation for ‘it’: it = take d4 (1 :> 2 :> Nil) <BLANKLINE>++#elif __GLASGOW_HASKELL__ == 906+>>> take d4               (1:>2:>Nil)+<BLANKLINE> <interactive>:...     • Couldn't match type ‘4 + n0’ with ‘2’       Expected: Vec (4 + n0) a@@ -1549,9 +1605,18 @@ >>> drop d0               (1:>2:>Nil) 1 :> 2 :> Nil -#if __GLASGOW_HASKELL__ == 906+#if __GLASGOW_HASKELL__ >= 910 >>> drop d4               (1:>2:>Nil)+<interactive>:...: error:...+    • Couldn't match...type ‘4 + n0...+      The type variable ‘n0’ is ambiguous+    • In the first argument of ‘print’, namely ‘it’+      In a stmt of an interactive GHCi command: print it <BLANKLINE>++#elif __GLASGOW_HASKELL__ == 906+>>> drop d4               (1:>2:>Nil)+<BLANKLINE> <interactive>:...: error:...     • Couldn't match...type ‘4 + n0...         The type variable ‘n0’ is ambiguous@@ -1943,9 +2008,7 @@  -- | \"'interleave' @d xs@\" creates a vector: ----- @--- \<x_0,x_d,x_(2d),...,x_1,x_(d+1),x_(2d+1),...,x_(d-1),x_(2d-1),x_(3d-1)\>--- @+-- > <x_0,x_d,x_(2d),...,x_1,x_(d+1),x_(2d+1),...,x_(d-1),x_(2d-1),x_(3d-1)> -- -- >>> let xs = 1 :> 2 :> 3 :> 4 :> 5 :> 6 :> 7 :> 8 :> 9 :> Nil -- >>> interleave d3 xs@@ -2366,7 +2429,27 @@ However, we cannot simply use 'fold' to create a tree-structure of 'Clash.Class.Num.add'es: -#if __GLASGOW_HASKELL__ >= 900+#if __GLASGOW_HASKELL__ >= 910+>>> :{+let populationCount' :: (KnownNat (n+1), KnownNat (n+2))+                     => BitVector (n+1) -> Index (n+2)+    populationCount' = fold add . map fromIntegral . bv2v+:}+<interactive>:...+    • Couldn't match type: ((n + 2) + (n + 2)) - 1+                     with: n + 2+      Expected: Index (n + 2) -> Index (n + 2) -> Index (n + 2)+        Actual: Index (n + 2)+                -> Index (n + 2) -> AResult (Index (n + 2)) (Index (n + 2))+    • In the first argument of ‘fold’, namely ‘add’+      In the first argument of ‘(.)’, namely ‘fold add’+      In the expression: fold add . map fromIntegral . bv2v+    • Relevant bindings include+        populationCount' :: BitVector (n + 1) -> Index (n + 2)+          (bound at ...)+<BLANKLINE>++#elif __GLASGOW_HASKELL__ >= 900 >>> :{ let populationCount' :: (KnownNat (n+1), KnownNat (n+2))                      => BitVector (n+1) -> Index (n+2)
+ src/Clash/Sized/Vector/ToTuple.hs view
@@ -0,0 +1,100 @@+{-|+Copyright  :  (C) 2024, Google LLC+License    :  BSD2 (see the file LICENSE)+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>++Tooling to safely work around @incomplete-uni-patterns@ and @incomplete-patterns@+warnings. See 'vecToTuple' for more information and examples.++Note: This module has been added to make upgrading to GHC 9.2 easier. As of GHC+      9.2, the @incomplete-uni-patterns@ has been added to the @-Wall@, making+      previously warning-free code now produce warnings.+-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TypeFamilyDependencies #-}++-- Purpose of this module+{-# OPTIONS_GHC -Wno-incomplete-patterns #-}++-- For debugging:+-- {-# OPTIONS_GHC -ddump-splices #-}++module Clash.Sized.Vector.ToTuple (VecToTuple(..)) where++import Clash.CPP+import Clash.Sized.Vector+import Clash.Sized.Vector.ToTuple.TH (vecToTupleInstances)++import Data.Tagged (Tagged(..))++#if MIN_VERSION_base(4,18,0)+import Data.Tuple (Solo(MkSolo))+#elif MIN_VERSION_base(4,16,0)+import Data.Tuple (Solo(Solo))+#endif++{- $setup+>>> :set -XMonoLocalBinds -XGADTs+>>> import Clash.Sized.Vector+-}++class VecToTuple a where+  type TupType a = r | r -> a++  -- | Given a vector with three elements:+  --+  -- >>> myVec = (1 :> 2 :> 3 :> Nil) :: Vec 3 Int+  --+  -- The following would produce a warning even though we can be sure+  -- no other pattern can ever apply:+  --+  -- >>> (a :> b :> c :> Nil) = myVec+  --+  -- 'vecToTuple' can be used to work around the warning:+  --+  -- >>> (a, b, c) = vecToTuple myVec+  --+  -- Of course, you will still get an error if you try to match a vector of the+  -- wrong length:+  --+  -- >>> (a, b, c, d) = vecToTuple myVec+  -- ...+#if __GLASGOW_HASKELL__ > 900+  --     • Couldn't match type: (a, b, c, d)+  --                      with: (Int, Int, Int)+#else+  --     • Couldn't match type: (Int, Int, Int)+  --                             ^+  --                      with: (a, b, c, d)+#endif+  -- ...+  vecToTuple ::  a -> TupType a++instance VecToTuple (Vec 0 a) where+  type TupType (Vec 0 a) = Tagged a ()+  vecToTuple _ = Tagged ()++#if MIN_VERSION_base(4,18,0)+-- | Instead of using 'vecToTuple' for @Vec 1 _@, you could also consider using 'head'+instance VecToTuple (Vec 1 a) where+  type TupType (Vec 1 a) = Solo a+  vecToTuple (a1 :> _) = MkSolo a1+#elif MIN_VERSION_base(4,16,0)+-- | Instead of using 'vecToTuple' for @Vec 1 _@, you could also consider using 'head'+instance VecToTuple (Vec 1 a) where+  type TupType (Vec 1 a) = Solo a+  vecToTuple (a1 :> _) = Solo a1+#endif++-- | __NB__: The documentation only shows instances up to /3/-tuples. By+-- default, instances up to and including /12/-tuples will exist. If the flag+-- @large-tuples@ is set instances up to the GHC imposed limit will exist. The+-- GHC imposed limit is either 62 or 64 depending on the GHC version.+instance VecToTuple (Vec 2 a) where+  type TupType (Vec 2 a) = (a, a)+  vecToTuple (a1 :> a2 :> _) = (a1, a2)++vecToTupleInstances maxTupleSize
+ src/Clash/Sized/Vector/ToTuple/TH.hs view
@@ -0,0 +1,64 @@+{-# OPTIONS_HADDOCK hide #-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE TemplateHaskellQuotes #-}++module Clash.Sized.Vector.ToTuple.TH (vecToTupleInstance, vecToTupleInstances) where++import Clash.Sized.Vector (Vec((:>)))+import Language.Haskell.TH++appTs :: Q Type -> [Q Type] -> Q Type+appTs = foldl appT++appPsInfix :: Name -> [Q Pat] -> Q Pat+appPsInfix f = foldl1 (\l r -> uInfixP l f r)++tupT :: [Q Type] -> Q Type+tupT tyArgs = tupleT (length tyArgs) `appTs` tyArgs++vecToTupleInstances :: Integer -> Q [Dec]+vecToTupleInstances n = mapM vecToTupleInstance [3..n]+++vecToTupleInstance :: Integer -> Q Dec+vecToTupleInstance n =+  instanceD+    -- No superclasses+    (pure [])++    -- Head+    (vecToTupleCon `appT` vecType)++    -- Implementation+    [ tySynInstD+#if !MIN_VERSION_template_haskell(2,15,0)+        (mkName "TupType")+#endif+        ( tySynEqn+#if MIN_VERSION_template_haskell(2,15,0)+            Nothing aTypeLhs+#else+            [vecType]+#endif+            aTypeRhs )+    , funD vecToTupleFunName [clause [vecToTuplePat] (normalB vecToTupleImpl) []]+    ]++ where+  vecToTupleCon = conT (mkName "VecToTuple")+  vecType = conT ''Vec `appT` litT (numTyLit n) `appT` varT (mkName "a")++  -- associated type+#if MIN_VERSION_template_haskell(2,15,0)+  tupTypeCon = conT (mkName "TupType")+  aTypeLhs = tupTypeCon `appT` vecType+#endif+  aTypeRhs = tupT [varT (mkName "a") | _ <- [1..n]]++  -- vecToTuple+  vecToTupleFunName = mkName "vecToTuple"+  vecToTuplePat = appPsInfix '(:>) (map varP varNames ++ [wildP])+  vecToTupleImpl = tupE (map varE varNames)++  varNames = map (mkName . ('a':) . show) [1..n]
src/Clash/Tutorial.hs view
@@ -234,24 +234,18 @@ <https://docs.haskellstack.org/en/stable/README/#how-to-install Stack>, you can start the Clash compiler in interpretive mode by: -@-stack exec --resolver lts-19 --package clash-ghc -- clashi-@+> stack exec --resolver lts-19 --package clash-ghc -- clashi  If instead you followed the [instructions](https://clash-lang.org/install/linux/) to setup a starter project with Stack, you can also run @clashi@ inside such a project. Change to the directory of the project, and invoke -@-stack run -- clashi-@+> stack run -- clashi  If you instead set up the starter project with GHC and Cabal, change to the directory of the project and invoke -@-cabal run -- clashi-@+> cabal run -- clashi  For those familiar with Haskell/GHC, this is indeed just @GHCi@, with three added commands (@:vhdl@, @:verilog@, and @:systemverilog@). You can load files@@ -643,6 +637,7 @@ -}  {- $mac6 #mac6#+ * __'Num' instance for 'Signal'__:      @'Signal' a@ is also also considered a 'Num'eric type as long as the value@@ -944,29 +939,27 @@  The Clash compiler will normally generate the following @topentity.vhdl@ file: -@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.Blinker_topEntity_types.all;--entity topEntity is-  port(-- clock-       clk    : in Blinker_topEntity_types.clk_DomInput;-       -- reset-       rst    : in Blinker_topEntity_types.rst_DomInput;-       eta    : in std_logic;-       result : out std_logic_vector(7 downto 0));-end;--architecture structural of topEntity is- ...-end;-@+> -- Automatically generated VHDL-93+> library IEEE;+> use IEEE.STD_LOGIC_1164.ALL;+> use IEEE.NUMERIC_STD.ALL;+> use IEEE.MATH_REAL.ALL;+> use std.textio.all;+> use work.all;+> use work.Blinker_topEntity_types.all;+>+> entity topEntity is+>   port(-- clock+>        clk    : in Blinker_topEntity_types.clk_DomInput;+>        -- reset+>        rst    : in Blinker_topEntity_types.rst_DomInput;+>        eta    : in std_logic;+>        result : out std_logic_vector(7 downto 0));+> end;+>+> architecture structural of topEntity is+>  ...+> end;  However, if we add the following 'Synthesize' annotation in the file: @@ -981,29 +974,27 @@  The Clash compiler will generate the following @blinker.vhdl@ file instead: -@--- Automatically generated VHDL-93-library IEEE;-use IEEE.STD_LOGIC_1164.ALL;-use IEEE.NUMERIC_STD.ALL;-use IEEE.MATH_REAL.ALL;-use std.textio.all;-use work.all;-use work.blinker_types.all;--entity blinker is-  port(-- clock-       CLOCK_50 : in blinker_types.clk_DomInput;-       -- reset-       KEY0     : in blinker_types.rst_DomInput;-       KEY1     : in std_logic;-       LED      : out std_logic_vector(7 downto 0));-end;--architecture structural of blinker is- ...-end;-@+> -- Automatically generated VHDL-93+> library IEEE;+> use IEEE.STD_LOGIC_1164.ALL;+> use IEEE.NUMERIC_STD.ALL;+> use IEEE.MATH_REAL.ALL;+> use std.textio.all;+> use work.all;+> use work.blinker_types.all;+>+> entity blinker is+>   port(-- clock+>        CLOCK_50 : in blinker_types.clk_DomInput;+>        -- reset+>        KEY0     : in blinker_types.rst_DomInput;+>        KEY1     : in std_logic;+>        LED      : out std_logic_vector(7 downto 0));+> end;+>+> architecture structural of blinker is+>  ...+> end;  Where we now have: @@ -1057,13 +1048,11 @@  For which the VHDL /expression/ primitive is: -@-BlackBox:-  name: \'Clash.Sized.Internal.Signed.*#\'-  kind: \'Expression\'-  type: \'(*#) :: KnownNat n => Signed n -> Signed n -> Signed n\'-  template: \'resize(~ARG[1] * ~ARG[2], ~LIT[0])\'-@+> BlackBox:+>   name: Clash.Sized.Internal.Signed.*#+>   kind: Expression+>   type: '(*#) :: KnownNat n => Signed n -> Signed n -> Signed n'+>   template: resize(~ARG[1] * ~ARG[2], ~LIT[0])  The @name@ of the primitive is the /fully qualified/ name of the function you are creating the primitive for. Because we are creating an /expression/@@ -1112,14 +1101,14 @@   => 'Clock' dom           -- ^ Clock to synchronize to   -> 'Enable' dom          -- ^ Global enable   -> 'Vec' n a             -- ^ Initial content of the BRAM, also-                           -- determines the size, @n@, of the BRAM.+                           -- determines the size, \@n\@, of the BRAM.                            ---                           -- __NB__: __MUST__ be a constant.-  -> 'Signal' dom Int      -- ^ Read address @r@+                           -- \_\_NB\_\_: \_\_MUST\_\_ be a constant.+  -> 'Signal' dom Int      -- ^ Read address \@r\@   -> 'Signal' dom Bool     -- ^ Write enable-  -> 'Signal' dom Int      -- ^ Write address @w@-  -> 'Signal' dom a        -- ^ Value to write (at address @w@)-  -> 'Signal' dom a        -- ^ Value of the @blockRAM@ at address @r@ from+  -> 'Signal' dom Int      -- ^ Write address \@w\@+  -> 'Signal' dom a        -- ^ Value to write (at address \@w\@)+  -> 'Signal' dom a        -- ^ Value of the BRAM at address \@r\@ from                            -- the previous clock cycle blockRam# (Clock _) gen content rd wen =   go@@ -1148,70 +1137,68 @@  And for which the /declaration/ primitive is: -@-BlackBox:-  name: Clash.Explicit.BlockRam.blockRam#-  kind: Declaration-  type: |--    blockRam#-      :: ( KnownDomain dom        ARG[0]-         , HasCallStack  --       ARG[1]-         , NFDataX a )   --       ARG[2]-      => Clock dom       -- clk,  ARG[3]-      -> Enable dom      -- en,   ARG[4]-      -> Vec n a         -- init, ARG[5]-      -> Signal dom Int  -- rd,   ARG[6]-      -> Signal dom Bool -- wren, ARG[7]-      -> Signal dom Int  -- wr,   ARG[8]-      -> Signal dom a    -- din,  ARG[9]-      -> Signal dom a-  template: |--    -- blockRam begin-    ~GENSYM[~RESULT_blockRam][1] : block-      signal ~GENSYM[~RESULT_RAM][2] : ~TYP[5] := ~CONST[5];-      signal ~GENSYM[rd][4]  : integer range 0 to ~LENGTH[~TYP[5]] - 1;-      signal ~GENSYM[wr][5]  : integer range 0 to ~LENGTH[~TYP[5]] - 1;-    begin-      ~SYM[4] <= to_integer(~ARG[6])-      -- pragma translate_off-                    mod ~LENGTH[~TYP[5]]-      -- pragma translate_on-                    ;-      ~SYM[5] <= to_integer(~ARG[8])-      -- pragma translate_off-                    mod ~LENGTH[~TYP[5]]-      -- pragma translate_on-                    ;-    ~IF ~VIVADO ~THEN-      ~SYM[6] : process(~ARG[3])-      begin-        if ~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[3]) then-          if ~ARG[7] ~IF ~ISACTIVEENABLE[4] ~THEN and ~ARG[4] ~ELSE ~FI then-            ~SYM[2](~SYM[5]) <= ~TOBV[~ARG[9]][~TYP[9]];-          end if;-          ~RESULT <= fromSLV(~SYM[2](~SYM[4]))-          -- pragma translate_off-          after 1 ps-          -- pragma translate_on-          ;-        end if;-      end process; ~ELSE-      ~SYM[6] : process(~ARG[3])-      begin-        if ~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[3]) then-          if ~ARG[7] ~IF ~ISACTIVEENABLE[4] ~THEN and ~ARG[4] ~ELSE ~FI then-            ~SYM[2](~SYM[5]) <= ~ARG[9];-          end if;-          ~RESULT <= ~SYM[2](~SYM[4])-          -- pragma translate_off-          after 1 ps-          -- pragma translate_on-          ;-        end if;-      end process; ~FI-    end block;-    --end blockRam-@+> BlackBox:+>   name: Clash.Explicit.BlockRam.blockRam#+>   kind: Declaration+>   type: |-+>     blockRam#+>       :: ( KnownDomain dom        ARG[0]+>          , HasCallStack  --       ARG[1]+>          , NFDataX a )   --       ARG[2]+>       => Clock dom       -- clk,  ARG[3]+>       -> Enable dom      -- en,   ARG[4]+>       -> Vec n a         -- init, ARG[5]+>       -> Signal dom Int  -- rd,   ARG[6]+>       -> Signal dom Bool -- wren, ARG[7]+>       -> Signal dom Int  -- wr,   ARG[8]+>       -> Signal dom a    -- din,  ARG[9]+>       -> Signal dom a+>   template: |-+>     -- blockRam begin+>     ~GENSYM[~RESULT_blockRam][1] : block+>       signal ~GENSYM[~RESULT_RAM][2] : ~TYP[5] := ~CONST[5];+>       signal ~GENSYM[rd][4]  : integer range 0 to ~LENGTH[~TYP[5]] - 1;+>       signal ~GENSYM[wr][5]  : integer range 0 to ~LENGTH[~TYP[5]] - 1;+>     begin+>       ~SYM[4] <= to_integer(~ARG[6])+>       -- pragma translate_off+>                     mod ~LENGTH[~TYP[5]]+>       -- pragma translate_on+>                     ;+>       ~SYM[5] <= to_integer(~ARG[8])+>       -- pragma translate_off+>                     mod ~LENGTH[~TYP[5]]+>       -- pragma translate_on+>                     ;+>     ~IF ~VIVADO ~THEN+>       ~SYM[6] : process(~ARG[3])+>       begin+>         if ~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[3]) then+>           if ~ARG[7] ~IF ~ISACTIVEENABLE[4] ~THEN and ~ARG[4] ~ELSE ~FI then+>             ~SYM[2](~SYM[5]) <= ~TOBV[~ARG[9]][~TYP[9]];+>           end if;+>           ~RESULT <= fromSLV(~SYM[2](~SYM[4]))+>           -- pragma translate_off+>           after 1 ps+>           -- pragma translate_on+>           ;+>         end if;+>       end process; ~ELSE+>       ~SYM[6] : process(~ARG[3])+>       begin+>         if ~IF~ACTIVEEDGE[Rising][0]~THENrising_edge~ELSEfalling_edge~FI(~ARG[3]) then+>           if ~ARG[7] ~IF ~ISACTIVEENABLE[4] ~THEN and ~ARG[4] ~ELSE ~FI then+>             ~SYM[2](~SYM[5]) <= ~ARG[9];+>           end if;+>           ~RESULT <= ~SYM[2](~SYM[4])+>           -- pragma translate_off+>           after 1 ps+>           -- pragma translate_on+>           ;+>         end if;+>       end process; ~FI+>     end block;+>     --end blockRam  Again, the @name@ of the primitive is the fully qualified name of the function you are creating the primitive for. Because we are creating a /declaration/@@ -1262,7 +1249,7 @@   @-fclash-vivado@ flag. To be used with in an @~IF .. ~THEN .. ~ELSE .. ~FI@   statement. * @~CMPLE[\<HOLE1\>][\<HOLE2\>]@: /1/ when @\<HOLE1\> \<= \<HOLE2\>@, otherwise /0/-* @~IW64@: /1/ when Int\/Word\/Integer types are represented with 64 bits in HDL.+* @~IW64@: /1/ when @Int@\/@Word@\/@Integer@ types are represented with 64 bits in HDL.   /0/ when they're represented by 32 bits. * @~TOBV[\<HOLE\>][\<TYPE\>]@: create conversion code that so that the   expression in @\<HOLE\>@ is converted to a bit vector (@std_logic_vector@).@@ -1290,7 +1277,7 @@   a 'KnownDomain', 'Reset', or 'Clock'. * @~PERIOD[N]@: Clock period of given domain. Errors when called on an argument   which is not a 'Clock', 'Reset', 'KnownDomain' or 'KnownConf'.-* @~ISACTIVEENABLE[N]@: Is the @(N+1)@'th argument a an Enable line NOT set to a+* @~ISACTIVEENABLE[N]@: Is the @(N+1)@'th argument a an Enable line __not__ set to a   constant True. Can be used instead of deprecated (and removed) template tag * @~ISSYNC[N]@: Does synthesis domain at the @(N+1)@'th argument have synchronous resets. Errors   when called on an argument which is not a 'Reset', 'Clock', 'Enable', 'KnownDomain' or 'KnownConf'.@@ -1301,7 +1288,7 @@   argument which is not a 'Clock', 'Reset', 'Enable', 'KnownDomain' or 'KnownConf'. * @~AND[\<HOLE1\>,\<HOLE2\>,..]@: Logically /and/ the conditions in the @\<HOLE\>@'s * @~VAR[\<NAME\>][N]@: Like @~ARG[N]@ but binds the argument to a variable named NAME.-  The @\<NAME\>@ can be left blank, then clash will come up with a (unique) name.+  The @\<NAME\>@ can be left blank, then Clash will come up with a (unique) name. * @~VARS[N]@: VHDL: Return the variables at the @(N+1)@'th argument. * @~NAME[N]@: Render the @(N+1)@'th string literal argument as an identifier   instead of a string literal. Fails when the @(N+1)@'th argument is not a@@ -1328,132 +1315,124 @@ {- $vprimitives For those who are interested, the equivalent Verilog primitives are: -@-BlackBox:-  name: Clash.Sized.Internal.Signed.*#-  kind: Expression-  type: \'(*#) :: KnownNat n => Signed n -> Signed n -> Signed n\'-  template: ~ARG[1] * ~ARG[2]-@+> BlackBox:+>   name: Clash.Sized.Internal.Signed.*#+>   kind: Expression+>   type: '(*#) :: KnownNat n => Signed n -> Signed n -> Signed n'+>   template: ~ARG[1] * ~ARG[2]  and -@-BlackBox:-  name: Clash.Explicit.BlockRam.blockRam#-  kind: Declaration-  outputReg: true-  type: |--    blockRam#-      :: ( KnownDomain dom        ARG[0]-         , HasCallStack  --       ARG[1]-         , NFDataX a )   --       ARG[2]-      => Clock dom       -- clk,  ARG[3]-      => Enable dom      -- en,   ARG[4]-      -> Vec n a         -- init, ARG[5]-      -> Signal dom Int  -- rd,   ARG[6]-      -> Signal dom Bool -- wren, ARG[7]-      -> Signal dom Int  -- wr,   ARG[8]-      -> Signal dom a    -- din,  ARG[9]-      -> Signal dom a-  template: |--    // blockRam begin-    reg ~TYPO ~GENSYM[~RESULT_RAM][1] [0:~LENGTH[~TYP[5]]-1];--    reg ~TYP[5] ~GENSYM[ram_init][3];-    integer ~GENSYM[i][4];-    initial begin-      ~SYM[3] = ~CONST[5];-      for (~SYM[4]=0; ~SYM[4] < ~LENGTH[~TYP[5]]; ~SYM[4] = ~SYM[4] + 1) begin-        ~SYM[1][~LENGTH[~TYP[5]]-1-~SYM[4]] = ~SYM[3][~SYM[4]*~SIZE[~TYPO]+:~SIZE[~TYPO]];-      end-    end-    ~IF ~ISACTIVEENABLE[4] ~THEN-    always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~GENSYM[~RESULT_blockRam][5]~IF ~VIVADO ~THEN-      if (~ARG[4]) begin-        if (~ARG[7]) begin-          ~SYM[1][~ARG[8]] <= ~ARG[9];-        end-        ~RESULT <= ~SYM[1][~ARG[6]];-      end~ELSE-      if (~ARG[7] & ~ARG[4]) begin-        ~SYM[1][~ARG[8]] <= ~ARG[9];-      end-      if (~ARG[4]) begin-        ~RESULT <= ~SYM[1][~ARG[6]];-      end~FI-    end~ELSE-    always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~SYM[5]-      if (~ARG[7]) begin-        ~SYM[1][~ARG[8]] <= ~ARG[9];-      end-      ~RESULT <= ~SYM[1][~ARG[6]];-    end~FI-    // blockRam end-@+> BlackBox:+>   name: Clash.Explicit.BlockRam.blockRam#+>   kind: Declaration+>   outputUsage: NonBlocking+>   type: |-+>     blockRam#+>       :: ( KnownDomain dom        ARG[0]+>          , HasCallStack  --       ARG[1]+>          , NFDataX a )   --       ARG[2]+>       => Clock dom       -- clk,  ARG[3]+>       => Enable dom      -- en,   ARG[4]+>       -> Vec n a         -- init, ARG[5]+>       -> Signal dom Int  -- rd,   ARG[6]+>       -> Signal dom Bool -- wren, ARG[7]+>       -> Signal dom Int  -- wr,   ARG[8]+>       -> Signal dom a    -- din,  ARG[9]+>       -> Signal dom a+>   template: |-+>     // blockRam begin+>     reg ~TYPO ~GENSYM[~RESULT_RAM][1] [0:~LENGTH[~TYP[5]]-1];+>+>     reg ~TYP[5] ~GENSYM[ram_init][3];+>     integer ~GENSYM[i][4];+>     initial begin+>       ~SYM[3] = ~CONST[5];+>       for (~SYM[4]=0; ~SYM[4] < ~LENGTH[~TYP[5]]; ~SYM[4] = ~SYM[4] + 1) begin+>         ~SYM[1][~LENGTH[~TYP[5]]-1-~SYM[4]] = ~SYM[3][~SYM[4]*~SIZE[~TYPO]+:~SIZE[~TYPO]];+>       end+>     end+>     ~IF ~ISACTIVEENABLE[4] ~THEN+>     always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~GENSYM[~RESULT_blockRam][5]~IF ~VIVADO ~THEN+>       if (~ARG[4]) begin+>         if (~ARG[7]) begin+>           ~SYM[1][~ARG[8]] <= ~ARG[9];+>         end+>         ~RESULT <= ~SYM[1][~ARG[6]];+>       end~ELSE+>       if (~ARG[7] & ~ARG[4]) begin+>         ~SYM[1][~ARG[8]] <= ~ARG[9];+>       end+>       if (~ARG[4]) begin+>         ~RESULT <= ~SYM[1][~ARG[6]];+>       end~FI+>     end~ELSE+>     always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~SYM[5]+>       if (~ARG[7]) begin+>         ~SYM[1][~ARG[8]] <= ~ARG[9];+>       end+>       ~RESULT <= ~SYM[1][~ARG[6]];+>     end~FI+>     // blockRam end  -}  {- $svprimitives And the equivalent SystemVerilog primitives are: -@-BlackBox:-  name: Clash.Sized.Internal.Signed.*#-  kind: Expression-  type: \'(*#) :: KnownNat n => Signed n -> Signed n -> Signed n\'-  template: ~ARG[1] * ~ARG[2]-@+> BlackBox:+>   name: Clash.Sized.Internal.Signed.*#+>   kind: Expression+>   type: '(*#) :: KnownNat n => Signed n -> Signed n -> Signed n'+>   template: ~ARG[1] * ~ARG[2]  and -@-BlackBox:-  name: Clash.Explicit.BlockRam.blockRam#-  kind: Declaration-  type: |--    blockRam#-      :: ( KnownDomain dom        ARG[0]-         , HasCallStack  --       ARG[1]-         , NFDataX a )   --       ARG[2]-      => Clock dom       -- clk,  ARG[3]-      -> Enable dom      -- en,   ARG[4]-      -> Vec n a         -- init, ARG[5]-      -> Signal dom Int  -- rd,   ARG[6]-      -> Signal dom Bool -- wren, ARG[7]-      -> Signal dom Int  -- wr,   ARG[8]-      -> Signal dom a    -- din,  ARG[9]-      -> Signal dom a-  template: |--    // blockRam begin-    ~SIGD[~GENSYM[RAM][1]][5];-    logic [~SIZE[~TYP[9]]-1:0] ~GENSYM[~RESULT_q][2];-    initial begin-      ~SYM[1] = ~CONST[5];-    end~IF ~ISACTIVEENABLE[4] ~THEN-    always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~GENSYM[~COMPNAME_blockRam][3]~IF ~VIVADO ~THEN-      if (~ARG[4]) begin-        if (~ARG[7]) begin-          ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];-        end-        ~SYM[2] <= ~SYM[1][~ARG[6]];-      end~ELSE-      if (~ARG[7] & ~ARG[4]) begin-        ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];-      end-      if (~ARG[4]) begin-        ~SYM[2] <= ~SYM[1][~ARG[6]];-      end~FI-    end~ELSE-    always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~SYM[3]-      if (~ARG[7]) begin-        ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];-      end-      ~SYM[2] <= ~SYM[1][~ARG[6]];-    end~FI-    assign ~RESULT = ~FROMBV[~SYM[2]][~TYP[9]];-    // blockRam end-@+> BlackBox:+>   name: Clash.Explicit.BlockRam.blockRam#+>   kind: Declaration+>   type: |-+>     blockRam#+>       :: ( KnownDomain dom        ARG[0]+>          , HasCallStack  --       ARG[1]+>          , NFDataX a )   --       ARG[2]+>       => Clock dom       -- clk,  ARG[3]+>       -> Enable dom      -- en,   ARG[4]+>       -> Vec n a         -- init, ARG[5]+>       -> Signal dom Int  -- rd,   ARG[6]+>       -> Signal dom Bool -- wren, ARG[7]+>       -> Signal dom Int  -- wr,   ARG[8]+>       -> Signal dom a    -- din,  ARG[9]+>       -> Signal dom a+>   template: |-+>     // blockRam begin+>     ~SIGD[~GENSYM[RAM][1]][5];+>     logic [~SIZE[~TYP[9]]-1:0] ~GENSYM[~RESULT_q][2];+>     initial begin+>       ~SYM[1] = ~CONST[5];+>     end~IF ~ISACTIVEENABLE[4] ~THEN+>     always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~GENSYM[~COMPNAME_blockRam][3]~IF ~VIVADO ~THEN+>       if (~ARG[4]) begin+>         if (~ARG[7]) begin+>           ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];+>         end+>         ~SYM[2] <= ~SYM[1][~ARG[6]];+>       end~ELSE+>       if (~ARG[7] & ~ARG[4]) begin+>         ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];+>       end+>       if (~ARG[4]) begin+>         ~SYM[2] <= ~SYM[1][~ARG[6]];+>       end~FI+>     end~ELSE+>     always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin : ~SYM[3]+>       if (~ARG[7]) begin+>         ~SYM[1][~ARG[8]] <= ~TOBV[~ARG[9]][~TYP[9]];+>       end+>       ~SYM[2] <= ~SYM[1][~ARG[6]];+>     end~FI+>     assign ~RESULT = ~FROMBV[~SYM[2]][~TYP[9]];+>     // blockRam end  -} @@ -1566,12 +1545,12 @@      , 'NFDataX' a      )   => 'Clock' wdom                     -- ^ Clock to which to synchronize the write port of the RAM-  -> 'Clock' rdom                     -- ^ Clock to which the read address signal, @r@, is synchronized to+  -> 'Clock' rdom                     -- ^ Clock to which the read address signal, \@r\@, is synchronized to   -> 'Enable' wdom                    -- ^ Global enable-  -> 'SNat' n                         -- ^ Size @n@ of the RAM-  -> 'Signal' rdom addr               -- ^ Read address @r@-  -> 'Signal' wdom (Maybe (addr, a))  -- ^ (write address @w@, value to write)-  -> 'Signal' rdom a                  -- ^ Value of the @RAM@ at address @r@+  -> 'SNat' n                         -- ^ Size \@n\@ of the RAM+  -> 'Signal' rdom addr               -- ^ Read address \@r\@+  -> 'Signal' wdom (Maybe (addr, a))  -- ^ (write address \@w\@, value to write)+  -> 'Signal' rdom a                  -- ^ Value of the RAM at address \@r\@ @  that the signal containing the read address __r__ is synchronized to a different@@ -1678,7 +1657,7 @@      , 'KnownDomain' rdom      , 2 <= addrSize )   => SNat addrSize-  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@+  -- ^ Size of the internally used addresses, the  FIFO contains \@2^addrSize\@   -- elements.   -> 'Clock' wdom   -- ^ Clock to which the write port is synchronized@@ -1693,7 +1672,7 @@   -> 'Signal' wdom (Maybe a)   -- ^ Element to insert   -> ('Signal' rdom a, 'Signal' rdom Bool, 'Signal' wdom Bool)-  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)+  -- ^ (Oldest element in the FIFO, \@empty\@ flag, \@full\@ flag) asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst wen ren rinc wdataM =   (rdata, rempty, wfull)  where@@ -1799,7 +1778,7 @@      , 'KnownDomain' rdom      , 2 <= addrSize )   => SNat addrSize-  -- ^ Size of the internally used addresses, the  FIFO contains @2^addrSize@+  -- ^ Size of the internally used addresses, the  FIFO contains \@2^addrSize\@   -- elements.   -> 'Clock' wdom   -- ^ Clock to which the write port is synchronized@@ -1814,7 +1793,7 @@   -> 'Signal' wdom (Maybe a)   -- ^ Element to insert   -> ('Signal' rdom a, 'Signal' rdom Bool, 'Signal' wdom Bool)-  -- ^ (Oldest element in the FIFO, @empty@ flag, @full@ flag)+  -- ^ (Oldest element in the FIFO, \@empty\@ flag, \@full\@ flag) asyncFIFOSynchronizer addrSize\@SNat wclk rclk wrst rrst wen ren rinc wdataM =   (rdata, rempty, wfull)  where
src/Clash/XException.hs view
@@ -63,6 +63,7 @@ import           Data.List.Infinite  (Infinite (..)) import           Data.List.NonEmpty  (NonEmpty) import           Data.Ord            (Down (Down))+import           Data.Proxy          (Proxy) import           Data.Ratio          (Ratio, numerator, denominator) import qualified Data.Semigroup      as SG import qualified Data.Monoid         as M@@ -397,6 +398,8 @@ printX x = putStrLn $ showX x  instance ShowX ()+-- | @since 1.8.2+instance ShowX (Proxy a) instance ShowX a => ShowX (Identity a) instance ShowX a => ShowX (Const a b) instance (ShowX (f a), ShowX (g a)) => ShowX (Product f g a)@@ -585,6 +588,8 @@ instance NFDataX a => NFDataX (NonEmpty a) instance (NFDataX a, NFDataX b) => NFDataX (Either a b) instance NFDataX a => NFDataX (Maybe a)+-- | @since 1.8.2+instance NFDataX (Proxy a) instance NFDataX a => NFDataX (Identity a) instance NFDataX a => NFDataX (Const a b) instance (NFDataX (f a), NFDataX (g a)) => NFDataX (Product f g a)
src/Clash/Xilinx/ClockGen.hs view
@@ -191,26 +191,22 @@ the wrong type, the GHC compiler will complain about satisfying @NumOutClocks@. The error message on GHC 9.4 and up is: -@-    • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks-                        (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst-                           ([...])-                           DomInput) <= 7-    • In the expression: clockWizard clkIn rstIn-@+>     • Cannot satisfy: clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+>                         (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+>                            ([...])+>                            DomInput) <= 7+>     • In the expression: clockWizard clkIn rstIn  On older GHC versions, the error message is: -@-    • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks-                             (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst-                                ([...])-                                DomInput)-                           <=? 7’-                     with ‘'True’-        arising from a use of ‘clockWizard’-    • In the expression: clockWizard clkIn rstIn-@+>     • Couldn't match type ‘clash-prelude-[...]:Clash.Clocks.Internal.NumOutClocks+>                              (clash-prelude-[...]:Clash.Clocks.Internal.ClocksSyncClocksInst+>                                 ([...])+>                                 DomInput)+>                            <=? 7’+>                      with ‘'True’+>         arising from a use of ‘clockWizard’+>     • In the expression: clockWizard clkIn rstIn  The above error message is also emitted when trying to instantiate more than 18 output clocks, as it will fail to find an instance. As the wizard supports no@@ -218,18 +214,14 @@ also cause a type checking error. On GHC 9.4 and up, the error for attempting to instantiate 8 clocks is: -@-    • Cannot satisfy: 8 <= 7-    • In the expression: clockWizard clkIn rstIn-@+>     • Cannot satisfy: 8 <= 7+>     • In the expression: clockWizard clkIn rstIn  On older GHC versions, the error message is less clear: -@-    • Couldn't match type ‘'False’ with ‘'True’-        arising from a use of ‘clockWizard’-    • In the expression: clockWizard clkIn rstIn-@+>     • Couldn't match type ‘'False’ with ‘'True’+>         arising from a use of ‘clockWizard’+>     • In the expression: clockWizard clkIn rstIn -}  {- $tcl