packages feed

clash-prelude 1.4.6 → 1.4.7

raw patch · 27 files changed

+436/−245 lines, 27 filesdep +extradep ~ghc-bignumdep ~hashabledep ~textPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: extra

Dependency ranges changed: ghc-bignum, hashable, text, time

API changes (from Hackage documentation)

+ Clash.Annotations.Primitive: instance GHC.Classes.Eq Clash.Annotations.Primitive.Primitive
+ Clash.Annotations.Primitive: instance GHC.Classes.Eq Clash.Annotations.Primitive.PrimitiveWarning
+ Clash.Annotations.Primitive: instance GHC.Classes.Eq a => GHC.Classes.Eq (Clash.Annotations.Primitive.PrimitiveGuard a)
- Clash.Explicit.RAM: asyncRam# :: (HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom Int -> Signal wdom Bool -> Signal wdom Int -> Signal wdom a -> Signal rdom a
+ Clash.Explicit.RAM: asyncRam# :: forall wdom rdom n a. (HasCallStack, KnownDomain wdom, KnownDomain rdom) => Clock wdom -> Clock rdom -> Enable wdom -> SNat n -> Signal rdom Int -> Signal wdom Bool -> Signal wdom Int -> Signal wdom a -> Signal rdom a
- Clash.Sized.Internal.BitVector: undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a
+ Clash.Sized.Internal.BitVector: undefError :: KnownNat n => String -> [BitVector n] -> a

Files

CHANGELOG.md view
@@ -1,4 +1,19 @@ # Changelog for the Clash project+## 1.4.7 *Jan 30th 2022*+Fixed:+  * Clash now shows days in time strings for compile runs which take longer than a day [#1989](https://github.com/clash-lang/clash-compiler/compare/issue-1989).+  * Types defined in the package head are no longer qualified in the package body when rendering VHDL [#1996](https://github.com/clash-lang/clash-compiler/issues/1996).+  * `asyncRam` with different read and write clocks no longer produce the wrong results in Haskell simulation. [#2031](https://github.com/clash-lang/clash-compiler/pull/2031)+  * `Clash.Explicit.RAM.asyncRam#` Haskell simulation incorrectly treated an _undefined_ write enable as asserted. It now causes an _undefined_ value to be written instead. This problem did not propagate to the other `asyncRam` functions, where the same condition would simultaneously lead to an undefined write address, which would be handled correctly. This problem also only affects Haskell simulation, not the generated HDL. [#2031](https://github.com/clash-lang/clash-compiler/pull/2031)+  * `Clash.Explicit.BlockRam.blockRam#` and `Clash.Explicit.BlockRam.File.blockRamFile#` Haskell simulation incorrectly treated an _undefined_ write enable as asserted. It now causes an _undefined_ value to be written instead. This problem did not propagate to the other `blockRam` functions, where the same condition would simultaneously lead to an undefined write address, which would be handled correctly. This problem also only affects Haskell simulation, not the generated HDL.([#2054](https://github.com/clash-lang/clash-compiler/pull/2054))++Internal changes:+  * Removed instances of `Hashable Term` and `Hashable Type` [#1986](https://github.com/clash-lang/clash-compiler/pull/1986)+  * Added structural equality on `Term` (`Clash.Core.Subst.eqTerm`) and `Type` (`Clash.Core.Subst.eqType`)++Internal fixes:+  * Enable used to be a `Bool` in the Blackbox DSL, so we could use `boolToBit`. However it now has its own type in the DSL (`Enable domainName`), so we've added a new conversion function in order to convert it to a Bool.+  ## 1.4.6 *Oct 26th 2021* 
clash-prelude.cabal view
@@ -1,6 +1,6 @@ Cabal-version:        2.2 Name:                 clash-prelude-Version:              1.4.6+Version:              1.4.7 Synopsis:             Clash: a functional hardware description language - Prelude library Description:   Clash is a functional hardware description language that borrows both its@@ -50,7 +50,8 @@ Maintainer:           QBayLogic B.V. <devops@qbaylogic.com> Copyright:            Copyright © 2013-2016, University of Twente,                                   2016-2017, Myrtle Software Ltd,-                                  2017-2019, QBayLogic B.V., Google Inc.+                                  2017-2019, QBayLogic B.V., Google Inc.,+                                  2020-2022, QBayLogic B.V. Category:             Hardware Build-type:           Custom @@ -318,11 +319,12 @@                       data-binary-ieee754       >= 0.4.4   && < 0.6,                       data-default-class        >= 0.1.2   && < 0.2,                       deepseq                   >= 1.4.1.0 && < 1.5,+                      extra                     >= 1.6.17  && < 1.8,                       ghc-prim                  >= 0.5.1.0 && < 0.8,                       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.4,+                      hashable                  >= 1.2.1.0  && < 1.5,                       half                      >= 0.2.2.3 && < 1.0,                       interpolate               >= 0.2     && < 0.3,                       lens                      >= 4.10    && < 5.1.0,@@ -334,16 +336,16 @@                       th-abstraction            >= 0.2.10 && < 0.5.0,                       th-lift                   >= 0.7.0    && < 0.9,                       th-orphans                >= 0.13.1   && < 1.0,-                      text                      >= 0.11.3.1 && < 1.3,+                      text                      >= 0.11.3.1 && < 2.1,                       text-show                 >= 3.7     && < 3.10,-                      time                      >= 1.8     && < 1.13,+                      time                      >= 1.8     && < 1.14,                       transformers              >= 0.5.2.0 && < 0.7,                       type-errors               >= 0.2.0.0 && < 0.3,                       uniplate                  >= 1.6.12  && < 1.7,                       vector                    >= 0.11    && < 1.0    if impl(ghc >= 9.0.0)-    Build-Depends:    ghc-bignum                >= 1.0      && < 1.1+    Build-Depends:    ghc-bignum                >= 1.0      && < 1.3   else     Build-Depends:    integer-gmp               >= 1.0.1.0  && < 2.0   if flag(large-tuples)@@ -402,11 +404,13 @@                  Clash.Tests.AutoReg                  Clash.Tests.BitPack                  Clash.Tests.BitVector+                 Clash.Tests.BlockRam                  Clash.Tests.DerivingDataRepr                  Clash.Tests.DerivingDataReprTypes                  Clash.Tests.Fixed                  Clash.Tests.FixedExhaustive                  Clash.Tests.NFDataX+                 Clash.Tests.Ram                  Clash.Tests.Reset                  Clash.Tests.Resize                  Clash.Tests.Signal
src/Clash/Annotations/Primitive.hs view
@@ -272,7 +272,7 @@   -- ^ Description of a primitive for a given 'HDL's in a file at 'FilePath'   | InlinePrimitive [HDL] String   -- ^ Description of a primitive for a given 'HDL's as an inline 'String'-  deriving (Show, Read, Data, Generic, NFData, Hashable)+  deriving (Show, Read, Data, Generic, NFData, Hashable, Eq)  -- | Primitive guard to mark a value as either not translatable or as having a -- blackbox with an optional extra warning. Helps Clash generate better error@@ -287,7 +287,9 @@   | HasBlackBox [PrimitiveWarning] a   -- ^ Marks a value as having a blackbox. Clash will error if it hasn't found   -- a blackbox.-    deriving (Show, Read, Data, Generic, NFData, Hashable, Functor, Foldable, Traversable, Binary)+  deriving+    ( Show, Read, Data, Generic, NFData, Hashable, Functor, Foldable+    , Traversable, Binary, Eq )  -- | Warning that will be emitted on instantiating a guarded value. data PrimitiveWarning@@ -296,7 +298,7 @@   -- instantiated in a non-testbench context.   | WarnAlways String   -- ^ Always emit warning upon primitive instantiation.-    deriving (Show, Read, Data, Generic, NFData, Hashable, Binary)+    deriving (Show, Read, Data, Generic, NFData, Hashable, Binary, Eq)  -- | Extract primitive definition from a PrimitiveGuard. Will yield Nothing -- for guards of value 'DontTranslate'.
src/Clash/Examples/Internal.hs view
@@ -105,7 +105,7 @@     s = register 0 (mux upDown (s + 1) (s - 1))  lfsrF' :: BitVector 16 -> BitVector 16-lfsrF' s = pack feedback ++# slice d15 d1 s+lfsrF' s = pack feedback ++# slice (SNat @15) d1 s   where     feedback = s!5 `xor` s!3 `xor` s!2 `xor` s!0 
src/Clash/Explicit/BlockRam.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2017, Myrtle Software Ltd,-                  2017     , Google Inc.+                  2017     , Google Inc.,+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  BlockRAM primitives @@ -234,7 +235,7 @@ 'Clash.Prelude.RAM.asyncRam' is /undefined/, and consequently, the first few output samples are also /undefined/. We use the utility function 'Clash.XException.printX' to conveniently filter out the undefinedness and-replace it with the string "X" in the few leading outputs.+replace it with the string @\"undefined\"@ in the first few leading outputs.  @ >>> printX $ sampleN 32 $ system2 prog systemClockGen resetGen enableGen@@ -364,7 +365,7 @@ When we simulate our system we see that it works. This time again, we need to disregard the first sample, because the initial output of a 'blockRam' is /undefined/. We use the utility function 'Clash.XException.printX'-to conveniently filter out the undefinedness and replace it with the string "X".+to conveniently filter out the undefinedness and replace it with the string @\"undefined\"@.  @ >>> printX $ sampleN 34 $ system3 prog2 systemClockGen resetGen enableGen@@ -695,7 +696,8 @@ -- | Create a blockRAM with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is /undefined/+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- @ -- bram40@@ -741,7 +743,8 @@ -- | Create a blockRAM with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is /undefined/+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- @ -- bram32@@ -768,9 +771,7 @@   -> Enable dom   -- ^ Global enable   -> Vec (2^n) a-  -- ^ Initial content of the BRAM, also-  -- determines the size, @2^n@, of-  -- the BRAM.+  -- ^ Initial content of the BRAM   --   -- __NB__: __MUST__ be a constant.   -> Signal dom (Unsigned n)@@ -788,7 +789,7 @@   ClearOnReset :: ResetStrategy 'True   NoClearOnReset :: ResetStrategy 'False --- | Version of blockram that has no default values set. May be cleared to a+-- | Version of blockram that has no default values set. May be cleared to an -- arbitrary state using a reset function. blockRamU    :: forall n dom a r addr@@ -811,7 +812,7 @@   -> SNat n   -- ^ Number of elements in BRAM   -> (Index n -> a)-  -- ^ If applicable (see first argument), reset BRAM using this function.+  -- ^ If applicable (see 'ResetStrategy' argument), reset BRAM using this function.   -> Signal dom addr   -- ^ Read address @r@   -> Signal dom (Maybe (addr, a))@@ -1006,10 +1007,16 @@    upd ram we waddr d = case maybeIsX we of     Nothing -> case maybeIsX waddr of-      Nothing -> fmap (const (seq waddr d)) ram-      Just wa -> Seq.update wa d ram+      Nothing -> -- Put the XException from `waddr` as the value in all+                 -- locations of `ram`.+                 seq waddr d <$ ram+      Just wa -> -- Put the XException from `we` as the value at address+                 -- `waddr`.+                 Seq.update wa (seq we d) ram     Just True -> case maybeIsX waddr of-      Nothing -> fmap (const (seq waddr d)) ram+      Nothing -> -- Put the XException from `waddr` as the value in all+                 -- locations of `ram`.+                 seq waddr d <$ ram       Just wa -> Seq.update wa d ram     _ -> ram {-# ANN blockRam# hasBlackBox #-}
src/Clash/Explicit/BlockRam/File.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd+                  2019     , Myrtle Software Ltd,+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  = Initializing a BlockRAM with a data file #usingramfiles# @@ -113,7 +114,8 @@ -- | Create a blockRAM with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:@@ -158,7 +160,8 @@ -- | Create a blockRAM with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:@@ -252,10 +255,16 @@      upd ram we waddr d = case maybeIsX we of       Nothing -> case maybeIsX waddr of-        Nothing -> fmap (const (seq waddr d)) ram-        Just wa -> Seq.update wa d ram+        Nothing -> -- Put the XException from `waddr` as the value in all+                   -- locations of `ram`.+                   seq waddr d <$ ram+        Just wa -> -- Put the XException from `we` as the value at address+                   -- `waddr`.+                   Seq.update wa (seq we d) ram       Just True -> case maybeIsX waddr of-        Nothing -> fmap (const (seq waddr d)) ram+        Nothing -> -- Put the XException from `waddr` as the value in all+                   -- locations of `ram`.+                   seq waddr d <$ ram         Just wa -> Seq.update wa d ram       _ -> ram 
src/Clash/Explicit/RAM.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd+                  2019     , Myrtle Software Ltd,+                  2022     , QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  RAM primitives with a combinational read port. -}@@ -34,16 +35,17 @@ import GHC.TypeLits          (KnownNat) import qualified Data.Sequence as Seq -import Clash.Explicit.Signal-  (unbundle, unsafeSynchronizer, KnownDomain, enable)+import Clash.Explicit.Signal (unbundle, KnownDomain, enable) import Clash.Promoted.Nat    (SNat (..), snatToNum, pow2SNat) import Clash.Signal.Internal (Clock (..), Signal (..), Enable, fromEnable)+import Clash.Signal.Internal.Ambiguous (clockPeriod) import Clash.Sized.Unsigned  (Unsigned)-import Clash.XException      (errorX, maybeIsX, fromJustX)+import Clash.XException      (errorX, maybeIsX, fromJustX, seqX)  -- | Create a RAM with space for 2^@n@ elements ----- * __NB__: Initial content of the RAM is 'undefined'+-- * __NB__: Initial content of the RAM is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --@@ -75,7 +77,8 @@  -- | Create a RAM with space for @n@ elements ----- * __NB__: Initial content of the RAM is 'undefined'+-- * __NB__: Initial content of the RAM is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --@@ -110,7 +113,8 @@  -- | RAM primitive asyncRam#-  :: ( HasCallStack+  :: forall wdom rdom n a+   . ( HasCallStack      , KnownDomain wdom      , KnownDomain rdom )   => Clock wdom@@ -131,29 +135,56 @@   -- ^ Value to write (at address @w@)   -> Signal rdom a   -- ^ Value of the @RAM@ at address @r@-asyncRam# wclk rclk en sz rd we wr din =-    unsafeSynchronizer wclk rclk dout+asyncRam# !_ !_ en sz rd we wr din = dout   where-    rd'  = unsafeSynchronizer rclk wclk rd     ramI = Seq.replicate-              (snatToNum sz)+              szI               (withFrozenCallStack (errorX "asyncRam#: initial value undefined"))-    en' = fromEnable (enable en we)-    dout = go ramI rd' en' wr din+    en0 = fromEnable (enable en we)+    dout = if rPeriod == wPeriod+           then goSingle ramI rd en0 wr din+           else go 0 ramI rd en0 wr din+    rPeriod = snatToNum (clockPeriod @rdom) :: Int+    wPeriod = snatToNum (clockPeriod @wdom) :: Int+    szI = snatToNum sz :: Int -    go :: Seq.Seq a -> Signal wdom Int -> Signal wdom Bool-       -> Signal wdom Int -> Signal wdom a -> Signal wdom a-    go !ram (r :- rs) (e :- es) (w :- ws) (d :- ds) =-      let ram' = upd ram e (fromEnum w) d+    goSingle :: Seq.Seq a -> Signal rdom Int -> Signal wdom Bool+       -> Signal wdom Int -> Signal wdom a -> Signal rdom a+    goSingle !ram (r :- rs) ~(e :- es) wt@(~(w :- ws)) dt@(~(d :- ds)) =+      let ram0 = upd ram e w d           o    = ram `Seq.index` r-      in  o :- go ram' rs es ws ds+      in  o :- (wt `seq` dt `seq` goSingle ram0 rs es ws ds) -    upd ram we' waddr d = case maybeIsX we' of+    -- Given+    --   tR = absolute time of next active edge of read clock+    --   tW = absolute time of next active edge of write clock+    -- relTime is defined as relTime = tW - tR+    --+    -- Put differently, relative time 0 points at the next active edge of the+    -- read clock, and relTime points at the next active edge of the write+    -- clock.+    go :: Int -> Seq.Seq a -> Signal rdom Int -> Signal wdom Bool+       -> Signal wdom Int -> Signal wdom a -> Signal rdom a+    go   relTime !ram rt@(~(r :- rs)) et@(~(e :- es)) wt@(~(w :- ws))+         dt@(~(d :- ds))+      | relTime < 0 = let ram0 = upd ram e w d+                      in wt `seq` dt `seq`+                         go (relTime + wPeriod) ram0 rt es ws ds+      | otherwise   = let o = ram `Seq.index` r+                      in o :- go (relTime - rPeriod) ram rs et wt dt++    upd ram we0 waddr d = case maybeIsX we0 of       Nothing -> case maybeIsX waddr of-        Nothing -> fmap (const (seq waddr d)) ram-        Just wa -> Seq.update wa d ram+        Nothing -> -- Put the XException from `waddr` as the value in all+                   -- locations of `ram`.+                   seq waddr d <$ ram+        Just wa -> -- Put the XException from `we` as the value at address+                   -- `waddr`.+                   Seq.update wa (seq we0 d) ram       Just True -> case maybeIsX waddr of-        Nothing -> fmap (const (seq waddr d)) ram-        Just wa -> Seq.update wa d ram+        Nothing -> -- Put the XException from `waddr` as the value in all+                   -- locations of `ram`.+                   seq waddr d <$ ram+        Just wa -> d `seqX` Seq.update wa d ram       _ -> ram {-# NOINLINE asyncRam# #-}
src/Clash/Explicit/ROM.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd+                  2019     , Myrtle Software Ltd,+                  2022     , QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  ROMs -}@@ -40,7 +41,8 @@ -- | A ROM with a synchronous read port, with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --@@ -66,7 +68,8 @@ -- | A ROM with a synchronous read port, with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --@@ -79,7 +82,7 @@   -> Enable dom   -- ^ Global enable   -> Vec n a-  -- ^ ROM content+  -- ^ ROM content, also determines the size, @n@, of the ROM   --   -- __NB:__ must be a constant   -> Signal dom addr@@ -98,7 +101,7 @@   -> Enable dom   -- ^ Global enable   -> Vec n a-  -- ^ ROM content+  -- ^ ROM content, also determines the size, @n@, of the ROM   --   -- __NB:__ must be a constant   -> Signal dom Int
src/Clash/Explicit/ROM/File.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd.+                  2019     , Myrtle Software Ltd.,+                  2022     , QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  = Initializing a ROM with a data file #usingromfiles# @@ -99,7 +100,8 @@ -- | A ROM with a synchronous read port, with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:@@ -139,7 +141,8 @@ -- | A ROM with a synchronous read port, with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:
src/Clash/Explicit/Reset.hs view
@@ -64,7 +64,7 @@ -- be de-asserted synchronously but it can still be asserted asynchronously. -- The reset assert is immediate, but reset de-assertion is delayed by two -- cycles.-+-- -- Normally, asynchronous resets can be both asynchronously asserted and -- de-asserted. Asynchronous de-assertion can induce meta-stability in the -- component which is being reset. To ensure this doesn't happen,
src/Clash/Intel/ClockGen.hs view
@@ -38,6 +38,8 @@ -- -- outputs a clock running at 100 MHz -- altpll @@"50MHzDom" @@"100MHzDom" (SSymbol @@"altpll50to100") clk50 rst -- @+--+-- See also the [ALTPLL (Phase-Locked Loop) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_altpll.pdf) altpll   :: forall domOut domIn name    . (KnownDomain domIn, KnownDomain domOut)@@ -81,6 +83,8 @@ -- @ -- -- respectively.+--+-- See also the [Altera Phase-Locked Loop (Altera PLL) IP Core User Guide](https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/altera_pll.pdf) alteraPll   :: (Clocks t, KnownDomain domIn, ClocksCxt t)   => SSymbol name
src/Clash/Prelude/BlockRam.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2019, Myrtle Software Ltd,-                  2017     , Google Inc.+                  2017     , Google Inc.,+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  BlockRAM primitives @@ -231,10 +232,10 @@  Again, we can simulate our system and see that it works. This time however, we need to disregard the first few output samples, because the initial content of an-'Clash.Prelude.RAM.asyncRam' is 'Clash.XException.undefined', and consequently, the first few-output samples are also 'Clash.XException.undefined'. We use the utility function+'Clash.Prelude.RAM.asyncRam' is /undefined/, and consequently, the first few+output samples are also /undefined/. We use the utility function 'Clash.XException.printX' to conveniently filter out the undefinedness and-replace it with the string "X" in the few leading outputs.+replace it with the string @\"undefined\"@ in the few leading outputs.  @ >>> printX $ sampleN @System 32 (system2 prog)@@ -362,8 +363,8 @@  When we simulate our system we see that it works. This time again, we need to disregard the first sample, because the initial output of a-'blockRam' is 'Clash.XException.undefined'. We use the utility function 'Clash.XException.printX'-to conveniently filter out the undefinedness and replace it with the string "X".+'blockRam' is /undefined/. We use the utility function 'Clash.XException.printX'+to conveniently filter out the undefinedness and replace it with the string @\"undefined\"@.  @ >>> printX $ sampleN @System 34 (system3 prog2)@@ -673,7 +674,8 @@ -- | Create a blockRAM with space for @n@ elements. -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'Clash.XException.undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- @ -- bram40@@ -770,7 +772,8 @@ -- | Create a blockRAM with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'Clash.XException.undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- @ -- bram32@@ -794,7 +797,7 @@      , KnownNat n      )   => Vec (2^n) a-  -- ^ Initial content of the BRAM, also determines the size, @2^n@, of the BRAM.+  -- ^ Initial content of the BRAM   --   -- __NB__: __MUST__ be a constant.   -> Signal dom (Unsigned n)
src/Clash/Prelude/BlockRam/File.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2019     , Myrtle Software Ltd-                  2017     , Google Inc.+                  2017     , Google Inc.,+                  2022     , QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  = Initializing a BlockRAM with a data file #usingramfiles# @@ -97,7 +98,8 @@ -- | Create a blockRAM with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:@@ -143,7 +145,8 @@ -- | Create a blockRAM with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:
src/Clash/Prelude/RAM.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017-2019, Myrtle Software Ltd-                  2017     , Google Inc.+                  2017     , Google Inc.,+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  RAM primitives with a combinational read port. -}@@ -34,7 +35,8 @@  -- | Create a RAM with space for @n@ elements. ----- * __NB__: Initial content of the RAM is 'undefined'+-- * __NB__: Initial content of the RAM is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --@@ -60,7 +62,8 @@  -- | Create a RAM with space for 2^@n@ elements ----- * __NB__: Initial content of the RAM is 'undefined'+-- * __NB__: Initial content of the RAM is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --
src/Clash/Prelude/ROM.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd+                  2019     , Myrtle Software Ltd,+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  ROMs -}@@ -48,7 +49,7 @@ asyncRom   :: (KnownNat n, Enum addr)   => Vec n a-  -- ^ ROM content+  -- ^ ROM content, also determines the size, @n@, of the ROM   --   -- __NB:__ must be a constant   -> addr@@ -81,7 +82,7 @@ asyncRom#   :: KnownNat n   => Vec n a-  -- ^ ROM content+  -- ^ ROM content, also determines the size, @n@, of the ROM   --   -- __NB:__ must be a constant   -> Int@@ -111,7 +112,7 @@      , HiddenClock dom      , HiddenEnable dom  )   => Vec n a-  -- ^ ROM content+  -- ^ ROM content, also determines the size, @n@, of the ROM   --   -- __NB:__ must be a constant   -> Signal dom (Unsigned m)@@ -124,7 +125,8 @@ -- | A ROM with a synchronous read port, with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- -- Additional helpful information: --
src/Clash/Prelude/ROM/File.hs view
@@ -1,9 +1,10 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.-                  2019     , Myrtle Software Ltd+                  2019     , Myrtle Software Ltd,+                  2022     , QBayLogic B.V. License    :  BSD2 (see the file LICENSE)-Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com>+Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>  = Initializing a ROM with a data file #usingromfiles# @@ -149,7 +150,7 @@   -> BitVector m   -- ^ The value of the ROM at address @rd@ asyncRomFile sz file = asyncRomFile# sz file . fromEnum--- Leave 'asyncRom' eta-reduced, see Note [Eta-reduction and unsafePerformIO initMem]+-- Leave 'asyncRomFile#' eta-reduced, see Note [Eta-reduction and unsafePerformIO initMem] {-# INLINE asyncRomFile #-}  -- Note [Eta-reduction and unsafePerformIO initMem]@@ -248,7 +249,8 @@ -- | A ROM with a synchronous read port, with space for @n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:@@ -289,7 +291,8 @@ -- | A ROM with a synchronous read port, with space for 2^@n@ elements -- -- * __NB__: Read value is delayed by 1 cycle--- * __NB__: Initial output value is 'undefined'+-- * __NB__: Initial output value is /undefined/, reading it will throw an+-- 'Clash.XException.XException' -- * __NB__: This function might not work for specific combinations of -- code-generation backends and hardware targets. Please check the support table -- below:
src/Clash/Signal/Bundle/Internal.hs view
@@ -1,9 +1,9 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell #-} -module Clash.Signal.Bundle.Internal where+module Clash.Signal.Bundle.Internal (deriveBundleTuples, idPrimitive) where -import           Control.Monad               (liftM)+import           Control.Monad.Extra         (concatMapM) import           Clash.Annotations.Primitive (Primitive(InlinePrimitive)) import           Clash.CPP                   (maxTupleSize) import           Clash.Signal.Internal       (Signal((:-)))@@ -20,10 +20,6 @@   ipJson = "[{\"Primitive\": {\"name\": \"" ++ show nm ++ "\", \"primType\": \"Function\"}}]"   ip = InlinePrimitive [minBound..maxBound] ipJson --- | Monadic version of concatMap-concatMapM :: Monad m => (a -> m [b]) -> [a] -> m [b]-concatMapM f xs = liftM concat (mapM f xs)- -- | Contruct all the tuple instances for Bundle. deriveBundleTuples   :: Name@@ -162,7 +158,7 @@            , unbundleSig, unbundleF, unbundlePrimAnn, unbundleNoInlineAnn            ] -mkFunTys :: Foldable t => t Type -> Type -> Type+mkFunTys :: Foldable t => t TH.Type -> TH.Type -> TH.Type mkFunTys args res= foldl' go res args  where   go l r = AppT (AppT ArrowT l) r
src/Clash/Signal/Internal.hs view
@@ -854,7 +854,7 @@ clockTag (Clock dom) = dom  -- | Clock generator for simulations. Do __not__ use this clock generator for--- for the /testBench/ function, use 'Clash.Explicit.Testbench.tbClockGen' instead.+-- the /testBench/ function, use 'Clash.Explicit.Testbench.tbClockGen' instead. -- -- To be used like: --
src/Clash/Sized/Internal/BitVector.hs view
@@ -153,7 +153,7 @@ import GHC.Natural                (naturalToInteger) #endif import GHC.Prim                   (dataToTag#)-import GHC.Stack                  (HasCallStack, withFrozenCallStack)+import GHC.Stack                  (withFrozenCallStack) import GHC.TypeLits               (KnownNat, Nat, type (+), type (-)) #if MIN_VERSION_base(4,15,0) import GHC.TypeNats               (natVal)@@ -1179,35 +1179,35 @@   -- error for infix operator-undefErrorI :: (HasCallStack, KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a+undefErrorI :: (KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a undefErrorI op bv1 bv2 = withFrozenCallStack $   errorX $ "Clash.Sized.BitVector." ++ op   ++ " called with (partially) undefined arguments: "   ++ show bv1 ++ " " ++ op ++" " ++ show bv2  -- error for prefix operator/function-undefErrorP :: (HasCallStack, KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a+undefErrorP :: (KnownNat m, KnownNat n) => String -> BitVector m -> BitVector n -> a undefErrorP op bv1 bv2 = withFrozenCallStack $   errorX $ "Clash.Sized.BitVector." ++ op   ++ " called with (partially) undefined arguments: "   ++ show bv1 ++ " " ++ show bv2  -- error for prefix operator/function-undefErrorP3 :: (HasCallStack, KnownNat m, KnownNat n, KnownNat o) => String -> BitVector m -> BitVector n -> BitVector o -> a+undefErrorP3 :: (KnownNat m, KnownNat n, KnownNat o) => String -> BitVector m -> BitVector n -> BitVector o -> a undefErrorP3 op bv1 bv2 bv3 = withFrozenCallStack $   errorX $ "Clash.Sized.BitVector." ++ op   ++ " called with (partially) undefined arguments: "   ++ show bv1 ++ " " ++ show bv2 ++ " " ++ show bv3  -- error for unary operator/function-undefErrorU :: (HasCallStack, KnownNat n) => String -> BitVector n -> a+undefErrorU :: KnownNat n => String -> BitVector n -> a -- undefErrorU op bv1 = undefError ("Clash.Sized.BitVector." ++ op) [bv1] undefErrorU op bv1 = withFrozenCallStack $   errorX $ "Clash.Sized.BitVector." ++ op   ++ " called with (partially) undefined argument: "   ++ show bv1 -undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a+undefError :: KnownNat n => String -> [BitVector n] -> a undefError op bvs = withFrozenCallStack $   errorX $ op   ++ " called with (partially) undefined arguments: "
src/Clash/Sized/Internal/BitVector.hs-boot view
@@ -10,11 +10,10 @@ module Clash.Sized.Internal.BitVector where  import GHC.TypeLits (KnownNat,Nat)-import GHC.Stack    (HasCallStack) import Data.Kind    (Type)  type role BitVector nominal data BitVector :: Nat -> Type data Bit -undefError :: (HasCallStack, KnownNat n) => String -> [BitVector n] -> a+undefError :: KnownNat n => String -> [BitVector n] -> a
src/Clash/Sized/RTree.hs view
@@ -336,7 +336,7 @@ import Data.Singletons import Data.Proxy -data IIndex (f :: 'TyFun' Nat *) :: *+data IIndex (f :: 'TyFun' Nat Type) :: Type type instance 'Apply' IIndex l = 'Index' ((2^l)+1)  populationCount' :: (KnownNat k, KnownNat (2^k))
src/Clash/Sized/Vector.hs view
@@ -2130,7 +2130,7 @@ -- import Data.Singletons -- import Data.Proxy ----- data Append (m :: Nat) (a :: *) (f :: 'TyFun' Nat *) :: *+-- data Append (m :: Nat) (a :: Type) (f :: 'TyFun' Nat Type) :: Type -- type instance 'Apply' (Append m a) l = 'Vec' (l + m) a -- -- append' xs ys = 'dfold' (Proxy :: Proxy (Append m a)) (const (':>')) ys xs@@ -2164,7 +2164,7 @@   where     go :: SNat n -> Vec n a -> (p @@ n)     go _ Nil                        = z-    go s (y `Cons` (ys :: Vec z a)) =+    go s (y `Cons` ys) =       let s' = s `subSNat` d1       in  f s' y (go s' ys) {-# NOINLINE dfold #-}@@ -2260,7 +2260,7 @@ import Data.Singletons import Data.Proxy -data IIndex (f :: 'TyFun' Nat *) :: *+data IIndex (f :: 'TyFun' Nat Type) :: Type type instance 'Apply' IIndex l = 'Index' ((2^l)+1)  populationCount' :: (KnownNat k, KnownNat (2^k))
src/Clash/Tutorial.hs view
@@ -906,24 +906,24 @@ import "Clash.Intel.ClockGen"  'createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}-'createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}+'createDomain' vSystem{vName=\"Dom100\", vPeriod=10000}  topEntity   :: Clock DomInput   -> Signal DomInput Bool-  -> Signal Dom50 Bit-  -> Signal Dom50 (BitVector 8)+  -> Signal Dom100 Bit+  -> Signal Dom100 (BitVector 8) topEntity clk rst =     'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . Clash.Prelude.isRising 1) pllOut rstSync 'enableGen'   where-    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom50 (SSymbol \@\"altpll50\") clk ('Clash.Signal.unsafeFromLowPolarity' rst)+    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom100 (SSymbol \@\"altpll100\") clk ('Clash.Signal.unsafeFromLowPolarity' rst)     rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeFromLowPolarity' pllStable) enableGen  blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)   where-    -- clock frequency = 50e6  (50 MHz)+    -- clock frequency = 100e6  (100 MHz)     -- led update rate = 333e-3 (every 333ms)-    cnt_max = 16650000 :: ('Index' 16650001) -- 50e6 * 333e-3+    cnt_max = 'maxBound' :: ('Index' 33300000) -- 100e6 * 333e-3      cntr' | cntr == cnt_max = 0           | otherwise       = cntr + 1@@ -946,17 +946,17 @@ use IEEE.MATH_REAL.ALL; use std.textio.all; use work.all;-use work.blinker_types.all;+use work.Blinker_topEntity_types.all; -entity topentity is+entity topEntity is   port(-- clock-       clk  : in blinker_types.clk_dominput;-       rst  : in boolean;-       x    : in std_logic;-       leds : out std_logic_vector(7 downto 0));+       clk    : in Blinker_topEntity_types.clk_DomInput;+       rst    : in boolean;+       x      : in std_logic;+       result : out std_logic_vector(7 downto 0)); end; -architecture structural of topentity is+architecture structural of topEntity is  ... end; @@@ -1458,7 +1458,7 @@ Clash supports designs multiple /clock/ (and /reset/) domains, though perhaps in a slightly limited form. What is possible is: -* Create clock primitives, such as PPLs, which have an accompanying HDL primitive+* Create clock primitives, such as PLLs, which have an accompanying HDL primitive   (described <#primitives later on> in this tutorial). * Explicitly assign clocks to memory primitives. * Synchronize between differently-clocked parts of your design in a type-safe@@ -1514,7 +1514,7 @@ What this means is that when Clash converts your design to VHDL/(System)Verilog, you end up with a top-level module/entity with multiple clock and reset ports for the different clock domains. If you're targeting an FPGA, you can use e.g. a-<https://www.altera.com/literature/ug/ug_altpll.pdf PPL> or+<https://www.altera.com/literature/ug/ug_altpll.pdf PLL> or <http://www.xilinx.com/support/documentation/user_guides/ug472_7Series_Clocking.pdf MMCM> to provide the clock signals. @@ -2176,7 +2176,7 @@      @     x =-      case 'resetKind' @@'System' of+      case 'resetKind' @'System' of         SAsynchronous -> \'a\'         SSynchronous -> \'b\'     @@@ -2393,41 +2393,41 @@ import Clash.Prelude import Clash.Explicit.Testbench -dotp :: SaturatingNum a-     => Vec (n + 1) a-     -> Vec (n + 1) a+dotp :: 'SaturatingNum' a+     => 'Vec' (n + 1) a+     -> 'Vec' (n + 1) a      -> a-dotp as bs = fold boundedAdd (zipWith boundedMul as bs)+dotp as bs = 'fold' 'boundedAdd' ('zipWith' 'boundedMul' as bs)  fir-  :: ( HiddenClockResetEnable dom-     , Default a-     , KnownNat n-     , SaturatingNum a-     , NFDataX a )-  => Vec (n + 1) a -> Signal dom a -> Signal dom a+  :: ( 'HiddenClockResetEnable' dom+     , 'KnownNat' n+     , 'SaturatingNum' a+     , 'NFDataX' a+     , 'Default' a )+  => 'Vec' (n + 1) a -> 'Signal' dom a -> 'Signal' dom a fir coeffs x_t = y_t   where-    y_t = dotp coeffs \<$\> bundle xs-    xs  = window x_t+    y_t = dotp coeffs \<$\> 'bundle' xs+    xs  = 'window' x_t  topEntity-  :: Clock  System-  -> Reset  System-  -> Enable System-  -> Signal System (Signed 16)-  -> Signal System (Signed 16)-topEntity = exposeClockResetEnable (fir (2:>3:>(-2):>8:>Nil))+  :: 'Clock'  'System'+  -> 'Reset'  'System'+  -> 'Enable' 'System'+  -> 'Signal' 'System' ('Signed' 16)+  -> 'Signal' 'System' ('Signed' 16)+topEntity = 'exposeClockResetEnable' (fir (2:>3:>(-2):>8:>'Nil')) {\-\# NOINLINE topEntity \#-\} -testBench :: Signal System Bool+testBench :: 'Signal' 'System' 'Bool' testBench = done   where-    testInput      = stimuliGenerator clk rst (2:>3:>(-2):>8:>Nil)-    expectedOutput = outputVerifier' clk rst (4:>12:>1:>20:>Nil)-    done           = expectedOutput (topEntity clk rst enableGen testInput)-    clk            = tbSystemClockGen (not \<$\> done)-    rst            = systemResetGen+    testInput      = 'stimuliGenerator' clk rst (2:>3:>(-2):>8:>'Nil')+    expectedOutput = 'outputVerifier'' clk rst (4:>12:>1:>20:>'Nil')+    done           = expectedOutput (topEntity clk rst 'enableGen' testInput)+    clk            = 'tbSystemClockGen' (not \<$\> done)+    rst            = 'systemResetGen' @  ==== Blinker circuit@@ -2487,102 +2487,38 @@ @ module Blinker where -import Clash.Prelude-import Clash.Intel.ClockGen--data LedMode-  = Rotate-  -- ^ After some period, rotate active led to the left-  | Complement-  -- ^ After some period, turn on all disable LEDs, and vice versa-  deriving (Generic, 'NFDataX')---- Define a synthesis domain with a clock with a period of 20000 /ps/.-'createDomain' 'vSystem'{vName=\"Input\", vPeriod=20000}+import "Clash.Signal"+import "Clash.Prelude"+import "Clash.Intel.ClockGen" --- Define a synthesis domain with a clock with a period of 50000 /ps/.-'createDomain' 'vSystem'{vName=\"Dom50\", vPeriod=50000}+'createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}+'createDomain' vSystem{vName=\"Dom100\", vPeriod=10000} -{\-\# ANN topEntity-  ('Synthesize'-    { t_name   = \"blinker\"-    , t_inputs = [ PortName \"CLOCK_50\"-                 , PortName \"KEY0\"-                 , PortName \"KEY1\"-                 ]-    , t_output = PortName \"LED\"-    }) \#-\} topEntity-  :: Clock Input-  -- ^ Incoming clock-  -> Signal Input Bool-  -- ^ Reset signal, straight from KEY0-  -> Signal Dom50 Bit-  -- ^ Mode choice, straight from KEY1. See \'LedMode\'.-  -> Signal Dom50 (BitVector 8)-  -- ^ Output containing 8 bits, corresponding to 8 LEDs-topEntity clk20 rstBtn modeBtn =-  exposeClockResetEnable-    (mealy blinkerT initialStateBlinkerT . isRising 1)-    clk50-    rstSync-    en-    modeBtn- where-  -- | Enable line for subcomponents: we'll keep it always running-  en = enableGen--  -- Start with the first LED turned on, in rotate mode, with the counter on zero-  initialStateBlinkerT = (1, Rotate, 0)--  -- Signal coming from the reset button is low when pressed, and high when-  -- not pressed. We convert this signal to the polarity of our domain with-  -- 'unsafeFromLowPolarity'.-  rst = 'Clash.Signal.unsafeFromLowPolarity' rstBtn--  -- Instantiate a PLL: this stabilizes the incoming clock signal and indicates-  -- when the signal is stable. We're also using it to transform an incoming-  -- clock signal running at 20 MHz to a clock signal running at 50 MHz.-  (clk50, pllStable) =-    altpll-      \@Dom50-      (SSymbol \@\"altpll50\")-      clk20-      rst--  -- Synchronize reset to clock signal coming from PLL. We want the reset to-  -- remain active while the PLL is NOT stable, hence the conversion with-  -- 'unsafeFromLowPolarity'-  rstSync =-    'Clash.Signal.resetSynchronizer'-      clk50-      (unsafeFromLowPolarity pllStable)-      en--flipMode :: LedMode -> LedMode-flipMode Rotate = Complement-flipMode Complement = Rotate+  :: Clock DomInput+  -> Signal DomInput Bool+  -> Signal Dom100 Bit+  -> Signal Dom100 (BitVector 8)+topEntity clk rst =+    'exposeClockResetEnable' ('mealy' blinkerT (1,False,0) . Clash.Prelude.isRising 1) pllOut rstSync 'enableGen'+  where+    (pllOut,pllStable) = 'Clash.Intel.ClockGen.altpll' \@Dom100 (SSymbol \@\"altpll100\") clk ('Clash.Signal.unsafeFromLowPolarity' rst)+    rstSync            = 'Clash.Signal.resetSynchronizer' pllOut ('Clash.Signal.unsafeFromLowPolarity' pllStable) -blinkerT-  :: (BitVector 8, LedMode, Index 16650001)-  -> Bool-  -> ((BitVector 8, LedMode, Index 16650001), BitVector 8)-blinkerT (leds, mode, cntr) key1R = ((leds', mode', cntr'), leds)+blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)   where-    -- clock frequency = 50e6  (50 MHz)+    -- clock frequency = 100e6  (100 MHz)     -- led update rate = 333e-3 (every 333ms)-    cnt_max = 16650000 :: Index 16650001 -- 50e6 * 333e-3+    cnt_max = 'maxBound' :: ('Index' 33300000) -- 100e6 * 333e-3      cntr' | cntr == cnt_max = 0           | otherwise       = cntr + 1 -    mode' | key1R     = flipMode mode+    mode' | key1R     = not mode           | otherwise = mode -    leds' | cntr == 0 =-              case mode of-                Rotate -> rotateL leds 1-                Complement -> complement leds+    leds' | cntr == 0 = if mode then complement leds+                                else rotateL leds 1           | otherwise = leds @ -}
src/Clash/XException.hs view
@@ -252,11 +252,11 @@  -- | Fully evaluate a value, returning 'Nothing' if it throws 'XException'. ----- > maybeX 42                  = Just 42--- > maybeX (XException msg)    = Nothing--- > maybeX (3, XException msg) = Nothing--- > maybeX (3, _|_)            = _|_--- > maybeX _|_                 = _|_+-- > maybeHasX 42                  = Just 42+-- > maybeHasX (XException msg)    = Nothing+-- > maybeHasX (3, XException msg) = Nothing+-- > maybeHasX (3, _|_)            = _|_+-- > maybeHasX _|_                 = _|_ -- maybeHasX :: NFData a => a -> Maybe a maybeHasX = maybeX hasX@@ -296,7 +296,7 @@ -- > isX 42                  = Right 42 -- > isX (XException msg)    = Left msg -- > isX (3, XException msg) = Right (3, XException msg)--- > isX (3, _|_)            = (3, _|_)+-- > isX (3, _|_)            = Right (3, _|_) -- > isX _|_                 = _|_ isX :: a -> Either String a isX a =
+ tests/Clash/Tests/BlockRam.hs view
@@ -0,0 +1,52 @@+{-# LANGUAGE NoImplicitPrelude #-}++module Clash.Tests.BlockRam (tests) where++import qualified Data.List as List+import Test.Tasty+import Test.Tasty.HUnit++import qualified Clash.Explicit.Prelude as E+import Clash.Explicit.BlockRam (blockRam#)+import Clash.Prelude++primRam+  :: Signal System Int+  -> Signal System Bool+  -> Signal System Int+  -> Signal System Int+  -> Signal System (Maybe Int)+primRam rd we wr din =+  maybeIsX <$> blockRam# clockGen enableGen (0 :> 1 :> Nil) rd we wr din++type PrimSamples = [(Int, Bool, Int, Int, Maybe Int)]++undefEn :: PrimSamples++-- Undefined enable:+--    The written-to address should read 'undefined', but other addresses+--    should still have their data.++--                               rd  enable     waddr      wdata      dout++undefEn =                     [ ( 0, undefined, 0        , 2        , Nothing)+                              , ( 0, False    , 0        , 3        , Just 0 )+                              , ( 1, False    , 0        , 3        , Nothing)+                              , ( 1, False    , 0        , 3        , Just 1 )+                              ]++primRamAssertion+  :: PrimSamples+  -> Assertion+primRamAssertion samples = actual @?= expectedOutput+ where+  (rd, we, wr, din, expectedOutput) = List.unzip5 samples+  actual = E.sampleN (List.length samples) $ primRam (fromList rd)+                                                     (fromList we)+                                                     (fromList wr)+                                                     (fromList din)++tests :: TestTree+tests = testGroup "BlockRam"+  [ testCase "Undefined enable" $ primRamAssertion undefEn+  ]
+ tests/Clash/Tests/Ram.hs view
@@ -0,0 +1,112 @@+-- Assert correct behavior:+--+-- Undefined enable:+--    The written-to address should read 'undefined', but other addresses+--    should still have their data.+--+-- Undefined write address:+--    All addresses should read 'undefined'.+--+-- Undefined write data:+--    The written-to address should read 'undefined', but other addresses+--    should still have their data.+--+-- Deasserted enable+--    It shouldn't matter that other write inputs are 'undefined'.+--+-- Deasserted enable, OOB address+--    It shouldn't matter that it is out of bounds.+--+-- Read address strictness+--    If the read result is not used, out-of-bounds read address shouldn't+--    matter (equivalent to issue #1458).++{-# LANGUAGE NoImplicitPrelude #-}++module Clash.Tests.Ram (tests) where++import qualified Data.List as L+import Test.Tasty+import Test.Tasty.HUnit++import Clash.Explicit.Prelude+import Clash.Explicit.RAM++type Ram = (   Signal System Int+            -> Signal System Bool+            -> Signal System Int+            -> Signal System Int+            -> Signal System (Maybe Int)+           )++ram :: Ram+ram rd we wr din =+  maybeIsX <$> asyncRam# clockGen clockGen enableGen d2 rd we wr din++maskOobRead :: Ram+maskOobRead rd we wr din =+  maybeIsX <$> mux (rd .<. 2) ram0 (pure 4)+ where+  ram0 = asyncRam# clockGen clockGen enableGen d2 rd we wr din++type Samples = [(Int, Bool, Int, Int, Maybe Int)]++initMem, undefEn, undefWAddr, undefWData, enFalse, enFalseOobWAddr,+  oobRAddrStrict+  :: Samples++--                               rd  enable     waddr      wdata      dout+initMem =                     [ ( 0, True     , 0        , 0        , Nothing)+                              , ( 0, True     , 1        , 1        , Just 0 )+                              ]++undefEn = initMem <>          [ ( 0, undefined, 0        , 2        , Just 0 )+                              , ( 0, False    , 0        , 3        , Nothing)+                              , ( 1, False    , 0        , 3        , Just 1 )+                              ]++undefWAddr = initMem <>       [ ( 0, True     , undefined, 2        , Just 0 )+                              , ( 0, False    , 0        , 3        , Nothing)+                              , ( 1, False    , 0        , 3        , Nothing)+                              ]++undefWData = initMem <>       [ ( 0, True     , 0        , undefined, Just 0 )+                              , ( 0, False    , 0        , 3        , Nothing)+                              , ( 1, False    , 0        , 3        , Just 1 )+                              ]++enFalse = initMem <>          [ ( 0, False    , undefined, undefined, Just 0)+                              , ( 0, False    , undefined, undefined, Just 0)+                              , ( 1, False    , undefined, undefined, Just 1)+                              ]++enFalseOobWAddr = initMem <>  [ ( 0, False    , 255      , 2        , Just 0 )+                              , ( 0, False    , 0        , 3        , Just 0 )+                              , ( 1, False    , 0        , 3        , Just 1 )+                              ]++oobRAddrStrict = initMem <>   [ ( 1, False    , 0        , 3        , Just 1 )+                              , ( 2, False    , 0        , 3        , Just 4 )+                              , ( 0, False    , 0        , 3        , Just 0 )+                              ]++ramAssertion+  :: Ram+  -> Samples+  -> Assertion+ramAssertion ram0 samples = actual @?= expectedOutput+ where+  (rd, we, wr, din, expectedOutput) = L.unzip5 samples+  actual = sampleN (L.length samples) $ ram0 (fromList rd)+                                             (fromList we)+                                             (fromList wr)+                                             (fromList din)+tests :: TestTree+tests = testGroup "Ram"+  [ testCase "Undefined enable" $ ramAssertion ram undefEn+  , testCase "Undefined write address" $ ramAssertion ram undefWAddr+  , testCase "Undefined write data" $ ramAssertion ram undefWData+  , testCase "Deasserted enable" $ ramAssertion ram enFalse+  , testCase "Deasserted enable, OOB address" $ ramAssertion ram enFalseOobWAddr+  , testCase "Read address strictness" $ ramAssertion maskOobRead oobRAddrStrict+  ]
tests/unittests.hs view
@@ -5,10 +5,12 @@ import qualified Clash.Tests.AutoReg import qualified Clash.Tests.BitPack import qualified Clash.Tests.BitVector+import qualified Clash.Tests.BlockRam import qualified Clash.Tests.DerivingDataRepr import qualified Clash.Tests.Fixed import qualified Clash.Tests.FixedExhaustive import qualified Clash.Tests.NFDataX+import qualified Clash.Tests.Ram import qualified Clash.Tests.Reset import qualified Clash.Tests.Resize import qualified Clash.Tests.Signal@@ -25,10 +27,12 @@   [ Clash.Tests.AutoReg.tests   , Clash.Tests.BitPack.tests   , Clash.Tests.BitVector.tests+  , Clash.Tests.BlockRam.tests   , Clash.Tests.DerivingDataRepr.tests   , Clash.Tests.Fixed.tests   , Clash.Tests.FixedExhaustive.tests   , Clash.Tests.NFDataX.tests+  , Clash.Tests.Ram.tests   , Clash.Tests.Reset.tests   , Clash.Tests.Resize.tests   , Clash.Tests.Signal.tests