packages feed

clash-prelude 1.6.3 → 1.6.4

raw patch · 18 files changed

+594/−143 lines, 18 filesdep ~hedgehogdep ~lensPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: hedgehog, lens

API changes (from Hackage documentation)

+ Clash.Annotations.BitRepresentation.Internal: SymLitTy' :: Text -> Type'
+ Clash.Class.BitPack.Internal: instance (Clash.Class.BitPack.Internal.BitPack (f a), Clash.Class.BitPack.Internal.BitPack (g a)) => Clash.Class.BitPack.Internal.BitPack (Data.Functor.Product.Product f g a)
+ Clash.Class.BitPack.Internal: instance (Clash.Class.BitPack.Internal.BitPack (f a), Clash.Class.BitPack.Internal.BitPack (g a)) => Clash.Class.BitPack.Internal.BitPack (Data.Functor.Sum.Sum f g a)
+ Clash.Class.BitPack.Internal: instance Clash.Class.BitPack.Internal.BitPack (f (g a)) => Clash.Class.BitPack.Internal.BitPack (Data.Functor.Compose.Compose f g a)
+ Clash.Class.BitPack.Internal: instance Clash.Class.BitPack.Internal.BitPack a => Clash.Class.BitPack.Internal.BitPack (Data.Functor.Const.Const a b)
+ Clash.Class.BitPack.Internal: instance Clash.Class.BitPack.Internal.BitPack a => Clash.Class.BitPack.Internal.BitPack (Data.Functor.Identity.Identity a)
+ Clash.Promoted.Nat: instance GHC.Show.Show (Clash.Promoted.Nat.SNatLE a b)
+ Clash.Sized.RTree: [RBranch] :: RTree d a -> RTree d a -> RTree (d + 1) a
+ Clash.Sized.RTree: [RLeaf] :: a -> RTree 0 a
+ Clash.Sized.RTree: scanlPar :: KnownNat n => (a -> a -> a) -> Vec (2 ^ n) a -> Vec (2 ^ n) a
+ Clash.Sized.RTree: scanrPar :: KnownNat n => (a -> a -> a) -> Vec (2 ^ n) a -> Vec (2 ^ n) a
+ Clash.Sized.RTree: thead :: RTree n a -> a
+ Clash.Sized.RTree: tlast :: RTree n a -> a
+ Clash.Sized.RTree: tscanl :: forall a n. KnownNat n => (a -> a -> a) -> RTree n a -> RTree n a
+ Clash.Sized.RTree: tscanr :: forall a n. KnownNat n => (a -> a -> a) -> RTree n a -> RTree n a
+ Clash.XException: instance (Clash.XException.NFDataX (f a), Clash.XException.NFDataX (g a)) => Clash.XException.NFDataX (Data.Functor.Product.Product f g a)
+ Clash.XException: instance (Clash.XException.NFDataX (f a), Clash.XException.NFDataX (g a)) => Clash.XException.NFDataX (Data.Functor.Sum.Sum f g a)
+ Clash.XException: instance (Clash.XException.ShowX (f a), Clash.XException.ShowX (g a)) => Clash.XException.ShowX (Data.Functor.Product.Product f g a)
+ Clash.XException: instance (Clash.XException.ShowX (f a), Clash.XException.ShowX (g a)) => Clash.XException.ShowX (Data.Functor.Sum.Sum f g a)
+ Clash.XException: instance Clash.XException.NFDataX (f (g a)) => Clash.XException.NFDataX (Data.Functor.Compose.Compose f g a)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Functor.Const.Const a b)
+ Clash.XException: instance Clash.XException.NFDataX a => Clash.XException.NFDataX (Data.Functor.Identity.Identity a)
+ Clash.XException: instance Clash.XException.ShowX (f (g a)) => Clash.XException.ShowX (Data.Functor.Compose.Compose f g a)
+ Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (Data.Functor.Const.Const a b)
+ Clash.XException: instance Clash.XException.ShowX a => Clash.XException.ShowX (Data.Functor.Identity.Identity a)

Files

CHANGELOG.md view
@@ -1,4 +1,33 @@ # Changelog for the Clash project+## 1.6.4 *Aug 30th 2022*+Fixed:++ * Input validation of the used arguments in blackboxes is now complete. [#2184](https://github.com/clash-lang/clash-compiler/pull/2184)+ * `Clash.Annotations.BitRepresentation.Deriving.deriveAnnotation` no longer has quadratic complexity in the size of the constructors and fields. [#2209](https://github.com/clash-lang/clash-compiler/pull/2209)+ * Fully resolve type synonyms when deriving bit representations. [#2209](https://github.com/clash-lang/clash-compiler/pull/2209)+ * Disregard ticks when determining whether terms are shared. Fixes [#2233](https://github.com/clash-lang/clash-compiler/issues/2233).+ * The blackbox parser will make sure it fully parses its input, and report an error when it can't. [#2237](https://github.com/clash-lang/clash-compiler/issues/2237)+ * Wrap ~ARG[n] in parentheses. Fixes [#2213](https://github.com/clash-lang/clash-compiler/issues/2213)+ * The VHDL shift primitives no longer generate bound check failures. Fixes [#2215](https://github.com/clash-lang/clash-compiler/issues/2215)+ * Evaluator fails impredicative type instantiation of error values [#2272](https://github.com/clash-lang/clash-compiler/issues/2272)+ * Fix out of bound errors in toEnum/fromSLV for sum types [#2220](https://github.com/clash-lang/clash-compiler/issues/2220)+ * Netlist generation fails for certain uses of GADTs [#2289](https://github.com/clash-lang/clash-compiler/issues/2289)+ * The documentation for `ANN TestBench` had it backwards; it now correctly indicates the annotation is on the test bench, not the device under test. [#1750](https://github.com/clash-lang/clash-compiler/issues/1750)++Fixes with minor changes:++ * `reduceXor` now produces a result if the argument has undefined bits instead of throwing an `XException` (the result is an undefined bit). `reduceAnd` and `reduceOr` already always produced a result. [#2244](https://github.com/clash-lang/clash-compiler/pull/2244)++Added:++ * Support for symbols in types while deriving bit representations. [#2209](https://github.com/clash-lang/clash-compiler/pull/2209)+ * Support for promoted data types while deriving bit representations. [#2209](https://github.com/clash-lang/clash-compiler/pull/2209)+ * `scanlPar` and `scanrPar` in Clash's Prelude, as well as the `RTree` versions `tscanl` and `tscanr`. These variants of `scanl1` and `scanr1` compile to a binary tree of operations, with a depth of `O(log(n))` (`n` being the length of the vector) rather than a depth of `n` for `scanl1` and `scanr1`. [#2177](https://github.com/clash-lang/clash-compiler/pull/2177)+ * The GADT constructors for `RTree` (`RLeaf` and `RBranch`) are now exported directly in addition to the patterns `LR` and `BR`. [#2177](https://github.com/clash-lang/clash-compiler/pull/2177)+ * Added the `~ISSCALAR` template which can be used to check if an argument is rendered to a scalar in HDL. [#2184](https://github.com/clash-lang/clash-compiler/pull/2184)+ * Added support for records and infix constructors when using `Clash.Annotations.BitRepresentation.Deriving.deriveAnnotation`. [#2191](https://github.com/clash-lang/clash-compiler/pull/2191)+ * Clash now contains instances for `ShowX`, `NFDataX` and `BitPack` on the newtypes from the Data.Functor modules (`Identity`, `Const`, `Compose`, `Product` and `Sum`). [#2218](https://github.com/clash-lang/clash-compiler/issues/2218)+ ## 1.6.3 *Apr 7th 2022* Fixed:   * Handle `~ISUNDEFINED` hole in black boxes for `BitVector` and for product types. This means that with `-fclash-aggressive-x-optimization-blackboxes`, resets are now omitted for _undefined_ reset values of such types as well. [#2117](https://github.com/clash-lang/clash-compiler/issues/2117)
clash-prelude.cabal view
@@ -1,6 +1,6 @@ Cabal-version:        2.2 Name:                 clash-prelude-Version:              1.6.3+Version:              1.6.4 Synopsis:             Clash: a functional hardware description language - Prelude library Description:   Clash is a functional hardware description language that borrows both its@@ -334,7 +334,7 @@                       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,+                      lens                      >= 4.10    && < 5.2.0,                       recursion-schemes         >= 5.1     && < 5.3,                       QuickCheck                >= 2.7     && < 2.15,                       reflection                >= 2       && < 2.2,
+ doc/scanlPar.svg view
@@ -0,0 +1,122 @@+<?xml version="1.0" encoding="UTF-8" standalone="no"?>+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">+<svg version="1.1" xmlns:xl="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns="http://www.w3.org/2000/svg" viewBox="219 175.5 192.5075 238.23173" width="192.5075" height="238.23173">+  <defs>+    <marker orient="auto" overflow="visible" markerUnits="strokeWidth" id="FilledArrow_Marker" stroke-linejoin="miter" stroke-miterlimit="10" viewBox="-1 -4 10 8" markerWidth="10" markerHeight="8" color="black">+      <g>+        <path d="M 8 0 L 0 -3 L 0 3 Z" fill="currentColor" stroke="currentColor" stroke-width="1"/>+      </g>+    </marker>+  </defs>+  <g id="Canvas_1" stroke="none" stroke-dasharray="none" stroke-opacity="1" fill="none" fill-opacity="1">+    <title>Canvas 1</title>+    <rect fill="white" x="219" y="175.5" width="192.5075" height="238.23173"/>+    <g id="Canvas_1_Layer_1">+      <title>Layer 1</title>+      <g id="Graphic_6">+        <path d="M 296.5717 223.9904 L 264.4283 223.9904 C 261.66686 223.9904 259.42828 226.22897 259.42828 228.9904 L 259.42828 261.13382 C 259.42828 263.89524 261.66686 266.13382 264.4283 266.13382 L 296.5717 266.13382 C 299.33314 266.13382 301.5717 263.89524 301.5717 261.13382 L 301.5717 228.9904 C 301.5717 226.22897 299.33314 223.9904 296.5717 223.9904 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_5">+        <text transform="translate(221.09912 178.5)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">x0</tspan>+        </text>+      </g>+      <g id="Graphic_4">+        <text transform="translate(277.89868 239.5621)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">f</tspan>+        </text>+      </g>+      <g id="Graphic_10">+        <text transform="translate(275.09912 178.5)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">x1</tspan>+        </text>+      </g>+      <g id="Graphic_16">+        <text transform="translate(328.817 177.5)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">x2</tspan>+        </text>+      </g>+      <g id="Graphic_22">+        <text transform="translate(382.5349 178.5)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">x3</tspan>+        </text>+      </g>+      <g id="Line_32">+        <line x1="280.5" y1="189.5" x2="280.50002" y2="223.9904" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_44">+        <path d="M 404.0075 223.9904 L 371.86407 223.9904 C 369.10265 223.9904 366.86407 226.22897 366.86407 228.9904 L 366.86407 261.13382 C 366.86407 263.89524 369.10265 266.13382 371.86407 266.13382 L 404.0075 266.13382 C 406.76893 266.13382 409.0075 263.89524 409.0075 261.13382 L 409.0075 228.9904 C 409.0075 226.22897 406.76893 223.9904 404.0075 223.9904 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_43">+        <text transform="translate(385.33447 239.5621)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">f</tspan>+        </text>+      </g>+      <g id="Line_45">+        <line x1="387.9358" y1="189.5" x2="387.9358" y2="223.9904" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_54">+        <path d="M 350.2896 290.9 L 318.14618 290.9 C 315.38475 290.9 313.14618 293.1386 313.14618 295.9 L 313.14618 328.04344 C 313.14618 330.80486 315.38475 333.04344 318.14618 333.04344 L 350.2896 333.04344 C 353.05103 333.04344 355.2896 330.80486 355.2896 328.04344 L 355.2896 295.9 C 355.2896 293.1386 353.05103 290.9 350.2896 290.9 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_53">+        <text transform="translate(331.51745 306.47172)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">f</tspan>+        </text>+      </g>+      <g id="Line_57">+        <line x1="334.2179" y1="188.5" x2="334.2179" y2="290.9" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_58">+        <line x1="280.50002" y1="266.13382" x2="313.14618" y2="311.9717" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_59">+        <line x1="337.11103" y1="188.5" x2="366.86407" y2="245.0621" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_60">+        <line x1="229.46592" y1="189.5" x2="259.42828" y2="245.0621" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_62">+        <path d="M 404.0075 352.3 L 371.86407 352.3 C 369.10265 352.3 366.86407 354.5386 366.86407 357.3 L 366.86407 389.44344 C 366.86407 392.20486 369.10265 394.44344 371.86407 394.44344 L 404.0075 394.44344 C 406.76893 394.44344 409.0075 392.20486 409.0075 389.44344 L 409.0075 357.3 C 409.0075 354.5386 406.76893 352.3 404.0075 352.3 Z" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Graphic_61">+        <text transform="translate(385.33447 367.87172)" fill="black">+          <tspan font-family="Courier" font-size="9" fill="black" x="0" y="9">f</tspan>+        </text>+      </g>+      <g id="Line_64">+        <line x1="387.9358" y1="266.13382" x2="387.9358" y2="352.3" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_65">+        <line x1="334.2179" y1="333.04344" x2="366.86407" y2="373.3717" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_69">+        <line x1="387.5349" y1="394.4435" x2="387.5349" y2="401.05173" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_74">+        <line x1="334.2179" y1="333.04344" x2="333.78143" y2="401.05193" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_75">+        <line x1="280.50002" y1="266.13382" x2="280.03418" y2="401.0518" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_78">+        <line x1="387.8149" y1="394.7235" x2="387.8149" y2="401.33173" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_80">+        <line x1="226.2908" y1="190.02326" x2="226.5296" y2="401.0535" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_82">+        <line x1="226.2908" y1="190.02326" x2="226.2908" y2="199.4823" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_83"/>+      <g id="Line_86"/>+      <g id="Line_91"/>+      <g id="Line_97">+        <line x1="337.11103" y1="188.5" x2="337.21555" y2="188.6987" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_98">+        <line x1="229.46592" y1="189.5" x2="229.52266" y2="189.60521" marker-end="url(#FilledArrow_Marker)" stroke="black" stroke-linecap="round" stroke-linejoin="round" stroke-width="1"/>+      </g>+      <g id="Line_99"/>+    </g>+  </g>+</svg>
src/Clash/Annotations/BitRepresentation/Deriving.hs view
@@ -1,6 +1,7 @@ {-| Copyright  :  (C) 2018, Google Inc.,                   2022, QBayLogic B.V.+                  2022, LUMI GUIDE FIETSDETECTIE B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -59,32 +60,35 @@ import qualified Clash.Annotations.BitRepresentation.Util   as Util -import           Clash.Annotations.Primitive (hasBlackBox)+import           Clash.Annotations.Primitive  (hasBlackBox) import           Clash.Class.BitPack   (BitPack, BitSize, pack, packXWith, unpack)-import           Clash.Class.Resize         (resize)-import           Language.Haskell.TH.Compat (mkTySynInstD)-import           Clash.Sized.BitVector      (BitVector, low, (++#))+import           Clash.Class.Resize           (resize)+import           Language.Haskell.TH.Compat   (mkTySynInstD)+import           Clash.Sized.BitVector        (BitVector, low, (++#)) import           Clash.Sized.Internal.BitVector (undefined#)-import           Control.DeepSeq            (NFData)-import           Control.Monad              (forM)+import           Control.Applicative          (liftA3)+import           Control.DeepSeq              (NFData)+import           Control.Monad                (forM) import           Data.Bits   (shiftL, shiftR, complement, (.&.), (.|.), zeroBits, popCount, bit, testBit,    Bits, setBit)-import           Data.Data                  (Data)+import           Data.Data                    (Data)+import           Data.Containers.ListUtils    (nubOrd) import           Data.List   (mapAccumL, zipWith4, sortOn, partition)-import           Data.Typeable              (Typeable)-import qualified Data.Map                   as Map-import           Data.Maybe                 (fromMaybe)-import qualified Data.Set                   as Set-import           Data.Proxy                 (Proxy(..))-import           GHC.Exts                   (Int(I#))-import           GHC.Generics               (Generic)-import           GHC.Integer.Logarithms     (integerLog2#)-import           GHC.TypeLits               (natVal)+import           Data.Typeable                (Typeable)+import qualified Data.Map                     as Map+import           Data.Maybe                   (fromMaybe)+import qualified Data.Set                     as Set+import           Data.Proxy                   (Proxy(..))+import           GHC.Exts                     (Int(I#))+import           GHC.Generics                 (Generic)+import           GHC.Integer.Logarithms       (integerLog2#)+import           GHC.TypeLits                 (natVal) import           Language.Haskell.TH import           Language.Haskell.TH.Syntax+import           Language.Haskell.TH.Datatype (resolveTypeSynonyms)  -- | Used to track constructor bits in packed derivation data BitMaskOrigin@@ -183,6 +187,10 @@ resolveCon :: NameMap -> Con -> Con resolveCon nmap (NormalC t (unzip -> (bangs, fTypes))) =   NormalC t $ zip bangs $ map (resolve nmap) fTypes+resolveCon nmap (RecC t (unzip3 -> (name, bangs, fTypes))) =+  RecC t $ zip3 name bangs $ map (resolve nmap) fTypes+resolveCon nmap (InfixC (leftB, leftTy) t (rightB, rightTy)) =+  InfixC (leftB, resolve nmap leftTy) t (rightB, resolve nmap rightTy) resolveCon _name constr =   error $ "Unexpected constructor: " ++ show constr @@ -248,12 +256,24 @@   InfixC _ nm _ -> nm   _ -> error $ "No GADT support" -constrFieldSizes-  :: Con-  -> (Name, [Q Exp])-constrFieldSizes con = do-  (conName con, map typeSize $ fieldTypes con)+mkLet :: String -> Q Exp -> (Q Dec, Q Exp)+mkLet nm qe = do+  let nm' = mkName nm+  (valD (varP nm') (normalB qe) [], varE nm') +fieldSizeLets :: [[Type]] -> ([Q Dec], [[Q Exp]])+fieldSizeLets fieldtypess = (fieldSizeDecls, fieldSizessExps)+  where+    nums = map show [(0 :: Int)..]+    uqFieldTypes = nubOrd (concat fieldtypess)+    uqFieldSizes = map typeSize uqFieldTypes+    (fieldSizeDecls, szVars) = unzip $ zipWith+                                 (\i sz -> mkLet ("_f" ++ i) sz)+                                 nums+                                 uqFieldSizes+    tySizeMap = Map.fromList (zip uqFieldTypes szVars)+    fieldSizessExps = map (map (tySizeMap Map.!)) fieldtypess+ complementInteger :: Int -> Integer -> Integer complementInteger 0 _i = 0 complementInteger size i =@@ -304,59 +324,82 @@   where     values = [shiftL 1 n | n <- ns] -overlapFieldAnnsL :: [[Q Exp]] -> [[Q Exp]]-overlapFieldAnnsL fieldSizess = map go fieldSizess+overlapFieldAnnsL :: [[Q Exp]] -> ([Q Dec], [[Q Exp]])+overlapFieldAnnsL fieldSizess = ([maxDecl],  resExp)   where-    fieldSizess'  = listE $ map listE fieldSizess-    constructorSizes = [| map sum $fieldSizess' |]-    go fieldSizes =+    (maxDecl, maxExp) = mkLet "_maxf" maxConstrSize+    resExp = map go fieldSizess+    fieldSizess' = listE $ map listE fieldSizess+    constructorSizes = [| map (sum @[] @Int) $fieldSizess' |]+    maxConstrSize = [| maximum $constructorSizes - 1 |]+    go fieldsizes =       snd $       mapAccumL         (\start size -> ([| $start - $size |], [| bitmask $start $size |]))-        [| maximum $constructorSizes - 1 |]-        fieldSizes+        maxExp+        fieldsizes -overlapFieldAnnsR :: [[Q Exp]] -> [[Q Exp]]-overlapFieldAnnsR fieldSizess = map go fieldSizess+overlapFieldAnnsR :: [[Q Exp]] -> ([Q Dec], [[Q Exp]])+overlapFieldAnnsR fieldSizess = (sumFieldDecl, resExp)   where-    fieldSizess'  = listE $ map listE fieldSizess-    constructorSizes = [| map sum $fieldSizess' |]-    go fieldSizes =+    resExp = zipWith go fieldSizess sumFieldExp++    nums = map show [(0 :: Int) ..]++    (sumFieldDecl, sumFieldExp)+      = unzip $ zipWith+          (\fs i -> mkLet ("_sumf" ++ i) [|sum @[] @Int $(listE fs)|])+          fieldSizess+          nums++    go fieldSizes sumFieldsSize =       snd $       mapAccumL         (\start size -> ([| $start - $size |], [| bitmask $start $size |]))-        [| maximum $constructorSizes - (maximum $constructorSizes - sum $(listE fieldSizes)) - 1 |]+        [| $sumFieldsSize - 1 |]         fieldSizes -wideFieldAnns :: [[Q Exp]] -> [[Q Exp]]-wideFieldAnns fieldSizess = zipWith id (map go constructorOffsets) fieldSizess+wideFieldAnns :: [[Q Exp]] -> ([Q Dec], [[Q Exp]])+wideFieldAnns fieldSizess = (decs, resExp)   where-    constructorSizes =-      map (AppE (VarE 'sum) <$>) (map listE fieldSizess)+    decs = (dataSizeDec:constrSizeDecs) ++ constrOffsetDecs+    resExp = zipWith id (map go constrOffsetsExps) fieldSizess+    nums = map show [(0 :: Int) ..] -    constructorOffsets :: [Q Exp]-    constructorOffsets =-      init $-      scanl-        (\offset size -> [| $offset + $size |])-        [| 0 |]-        constructorSizes+    constrSizeExps :: [Q Exp]+    (constrSizeDecs, constrSizeExps)+      = unzip $ zipWith+          (\fs i -> mkLet ("_sumf" ++ i) [|sum @[] @Int $(listE fs)|])+          fieldSizess+          nums -    dataSize = [| sum $(listE constructorSizes) |]+    constrOffsetsExps :: [Q Exp]+    (last -> constrOffsetDecs, constrOffsetsExps) =+      unzip $ init $ scanl+        (\(ds, offset) (size, i) ->+          let e = [| $offset + $size |]+              (d, ve) = mkLet ("_constroffset" ++ i) e+          in (d:ds, ve)+        )+        ([], [| 0 |])+        (zip constrSizeExps nums) +    dataSizeExp :: Q Exp+    (dataSizeDec, dataSizeExp)+      = mkLet "_widedatasize" [| sum @[] @Int $(listE constrSizeExps) - 1 |]     go :: Q Exp -> [Q Exp] -> [Q Exp]     go offset fieldSizes =       snd $       mapAccumL         (\start size -> ([| $start - $size |], [| bitmask $start $size |]))-        [| $dataSize - 1 - $offset |]+        [| $dataSizeExp - $offset |]         fieldSizes  -- | Derive DataRepr' for a specific type. deriveDataRepr   :: ([Int] -> [(BitMask, Value)])   -- ^ Constructor derivator-  -> ([[Q Exp]] -> [[Q Exp]])+  -> ([[Q Exp]] -> ([Q Dec], [[Q Exp]]) )   -- ^ Field derivator   -> Derivator deriveDataRepr constrDerivator fieldsDerivator typ = do@@ -365,34 +408,54 @@     (TyConI (DataD [] _constrName vars _kind dConstructors _clauses)) ->       let varMap = Map.fromList $ zip (map tyVarBndrName vars) typeArgs in       let resolvedConstructors = map (resolveCon varMap) dConstructors in do+      let nums = map show [(0 :: Int)..]+      let fieldtypess = map fieldTypes resolvedConstructors +      let (fieldSzDecs, fieldSizess) = fieldSizeLets fieldtypess+       -- Get sizes and names of all constructors-      let-        (constrNames, fieldSizess) =-          unzip $ map constrFieldSizes resolvedConstructors+      let constrNames = map conName resolvedConstructors        let         (constrMasks, constrValues) =           unzip $ constrDerivator [0..length dConstructors - 1] -      let constrSize    = 1 + (msb $ maximum constrMasks)-      let fieldAnns     = fieldsDerivator fieldSizess-      let fieldAnnsFlat = listE $ concat fieldAnns+      let constrSize = 1 + (msb $ maximum @[] @Integer constrMasks)+      let (fieldDecs, fieldAnns) = fieldsDerivator fieldSizess +      -- extract field annotations into declarations+      let mkAnnDecl i j an = mkLet ("_fa" ++ i ++ "_" ++ j) an+      let+        fieldAnnTup =+          zipWith (\i -> zipWith (mkAnnDecl i) nums) nums fieldAnns++      let+        (fieldAnnDecs, fieldAnnVars) =+          (concat $ map (map fst) fieldAnnTup, map (map snd) fieldAnnTup)++      let fieldAnnsFlat = listE $ concat fieldAnnVars+       let dataSize | null $ concat fieldAnns = [| 0 |]-                   | otherwise = [| 1 + (msb $ maximum $ $fieldAnnsFlat) |]+                   | otherwise = [| 1 + (msb $ maximum @[] @Integer $ $fieldAnnsFlat) |] +      -- Extract data size into a declaration+      let (dataSizeDec, dataSizeExp) = mkLet "_datasize" dataSize++      let decls = (dataSizeDec:fieldSzDecs) ++ fieldDecs ++ fieldAnnDecs+       -- Determine at which bits various fields start       let constrReprs = zipWith4-                          (buildConstrRepr dataSize)+                          (buildConstrRepr dataSizeExp)                           constrNames-                          fieldAnns+                          fieldAnnVars                           constrMasks                           constrValues -      [| DataReprAnn-          $(liftQ $ return typ)-          ($dataSize + constrSize)+      resolvedType <- resolveTypeSynonyms typ++      letE decls [| DataReprAnn+          $(liftQ $ return resolvedType)+          ($dataSizeExp + constrSize)           $(listE constrReprs) |]     _ ->       fail $ "Could not derive dataRepr for: " ++ show info@@ -722,8 +785,11 @@ collectDataReprs :: Q [DataReprAnn] collectDataReprs = do   thisMod <- thisModule-  go [thisMod] Set.empty []+  unresolved <- go [thisMod] Set.empty []+  mapM resolveTyps unresolved   where+    resolveTyps (DataReprAnn t s c)+      = liftA3 DataReprAnn (resolveTypeSynonyms t) (pure s) (pure c)     go []     _visited acc = return acc     go (x:xs) visited  acc       | x `Set.member` visited = go xs visited acc@@ -924,8 +990,9 @@ deriveBitPack typQ = do   anns <- collectDataReprs   typ  <- typQ+  rTyp <- resolveTypeSynonyms typ -  ann <- case filter (\(DataReprAnn t _ _) -> t == typ) anns of+  ann <- case filter (\(DataReprAnn t _ _) -> t == rTyp) anns of               [a] -> return a               []  -> fail "No custom bit annotation found."               _   -> fail "Overlapping bit annotations found."
src/Clash/Annotations/BitRepresentation/Internal.hs view
@@ -1,5 +1,6 @@ {-| Copyright  :  (C) 2018, Google Inc.+                  2022, LUMI GUIDE FIETSDETECTIE B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  Christiaan Baaij <christiaan.baaij@gmail.com> -}@@ -44,6 +45,8 @@   -- ^ Qualified name of type   | LitTy' Integer   -- ^ Numeral literal (used in BitVector 10, for example)+  | SymLitTy' Text.Text+  -- ^ Symbol literal (used in for example (Signal "System" Int))   deriving (Generic, NFData, Eq, Typeable, Hashable, Ord, Show)  -- | Internal version of DataRepr@@ -90,8 +93,10 @@ thTypeToType' ty = go ty   where     go (TH.ConT name')   = ConstTy' (thToText name')+    go (TH.PromotedT name') = ConstTy' (thToText name')     go (TH.AppT ty1 ty2) = AppTy' (go ty1) (go ty2)     go (TH.LitT (TH.NumTyLit n)) = LitTy' n+    go (TH.LitT (TH.StrTyLit lit)) = SymLitTy' (Text.pack lit)     go _ = error $ "Unsupported type: " ++ show ty  -- | Convenience type for index built by buildCustomReprs
src/Clash/Annotations/TH.hs view
@@ -151,7 +151,7 @@ errorContext :: Tracked Q String errorContext = asks snd --- | Failure message with prefix in a 'Tracked' context+-- Failure message with prefix in a 'Tracked' context failMsgWithContext :: String -> Tracked Q String failMsgWithContext s = (++) (failMsg s) <$> errorContext @@ -402,7 +402,7 @@ gatherNames =   para typeTreeToPorts . guardPorts --- | Build a possible failing 'PortName' tree and unwrap the 'Naming' result.+-- Build a possible failing 'PortName' tree and unwrap the 'Naming' result. buildPorts   :: Type   -- ^ Type to investigate
src/Clash/Annotations/TopEntity.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2015-2016, University of Twente,                   2017     , Google Inc.,-                  2021     , QBayLogic B.V.+                  2021-2022, QBayLogic B.V. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com> @@ -206,21 +206,25 @@  === 'TestBench' annotation -Tell what binder is the 'TestBench' for a 'Synthesize'-annotated binder.--So in the following example, /f/ has a 'Synthesize' annotation, and /g/ is-the HDL test bench for /f/.+Tell what binder is the test bench for a 'Synthesize'-annotated binder.  @-f :: Bool -> Bool-f = ...-{\-\# ANN f (defSyn "f") \#-\}-{\-\# ANN f (TestBench \'g) \#-\}+entityBeingTested :: ...+entityBeingTested = ...+{\-\# NOINLINE entityBeingTested \#-\}+{\-\# ANN entityBeingTested (defSyn "entityBeingTested") \#-\} -g :: Signal Bool-g = ...++myTestBench :: Signal System Bool+myTestBench = ... entityBeingTested ...+{\-\# NOINLINE myTestBench \#-\}+{\-\# ANN myTestBench (TestBench \'entityBeingTested) \#-\} @ +The 'TestBench' annotation actually already implies a 'Synthesize' annotation on+the device under test, so the 'defSyn' in the example could have been omitted.+We recommend you supply 'defSyn' explicitly nonetheless. In any case, it will+still need the @NOINLINE@ annotation. -}  {-# LANGUAGE CPP #-}@@ -266,17 +270,9 @@   }   -- | Tell what binder is the 'TestBench' for a 'Synthesize'-annotated binder.   ---  -- So in the following example, /f/ has a 'Synthesize' annotation, and /g/ is-  -- the HDL test bench for /f/.-  --   -- @-  -- f :: Bool -> Bool-  -- f = ...-  -- {\-\# ANN f (defSyn "f") \#-\}-  -- {\-\# ANN f (TestBench \'g) \#-\}-  ---  -- g :: Signal Bool-  -- g = ...+  -- {\-\# NOINLINE myTestBench \#-\}+  -- {\-\# ANN myTestBench (TestBench \'entityBeingTested) \#-\}   -- @   | TestBench TH.Name   deriving (Eq,Data,Show,Generic)
src/Clash/Class/BitPack/Internal.hs view
@@ -1,7 +1,7 @@ {-| Copyright  :  (C) 2013-2016, University of Twente,                   2016-2017, Myrtle Software Ltd,-                  2021,      QBayLogic B.V.,+                  2021-2022  QBayLogic B.V.,                   2022,      Google Inc. License    :  BSD2 (see the file LICENSE) Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>@@ -31,6 +31,11 @@                                        wordToFloat)  import Data.Complex                   (Complex)+import Data.Functor.Compose           (Compose)+import Data.Functor.Const             (Const)+import Data.Functor.Identity          (Identity)+import Data.Functor.Product           (Product)+import Data.Functor.Sum               (Sum) import Data.Int import Data.Ord                       (Down) import Data.Word@@ -449,6 +454,12 @@ instance BitPack a => BitPack (Complex a) instance BitPack a => BitPack (Down a) +instance BitPack a => BitPack (Identity a)+instance BitPack a => BitPack (Const a b)+instance (BitPack (f a), BitPack (g a)) => BitPack (Product f g a)+instance (BitPack (f a), BitPack (g a)) => BitPack (Sum f g a)+instance BitPack (f (g a)) => BitPack (Compose f g a)+ -- | Zero-extend a 'Bool'ean value to a 'BitVector' of the appropriate size. -- -- >>> boolToBV True :: BitVector 6@@ -462,7 +473,7 @@ boolToBit :: Bool -> Bit boolToBit = bitCoerce --- | Convert a Bool to a Bit+-- | Convert a Bit to a Bool bitToBool :: Bit -> Bool bitToBool = bitCoerce 
src/Clash/Promoted/Nat.hs view
@@ -328,6 +328,8 @@   SNatLE :: forall a b . a <= b => SNatLE a b   SNatGT :: forall a b . (b+1) <= a => SNatLE a b +deriving instance Show (SNatLE a b)+ -- | Get an ordering relation between two SNats compareSNat :: forall a b . SNat a -> SNat b -> SNatLE a b compareSNat a b =
src/Clash/Signal.hs view
@@ -1304,6 +1304,7 @@ -- See Note [Going from WithSingleDomain to WithSpecificDomain] {-# INLINE andEnable #-} +#ifdef CLASH_MULTIPLE_HIDDEN {- | Merge enable signal with signal of bools by applying the boolean AND operation. @@ -1320,7 +1321,6 @@  <#hiddenclockandreset Click here to read more about hidden clocks, resets, and enables> -#ifdef CLASH_MULTIPLE_HIDDEN === __Example__ 'andSpecificEnable' can only be used when it can find the specified domain in /r/:@@ -1336,8 +1336,8 @@ reg = 'register' @@dom 5 (reg + 1) f en = 'andSpecificEnable' @@dom en reg @-#endif -}+#endif andSpecificEnable   :: forall dom r    . ( HiddenEnable dom
src/Clash/Sized/Internal/BitVector.hs view
@@ -847,21 +847,33 @@      sz    = natVal bv     maxI  = (2 ^ sz) - 1-reduceAnd# bv = V.foldl (.&.) 1 (V.bv2v bv)+reduceAnd# bv@(BV m i) =+    -- If any defined bit is 0, i.e., 'm .|. i /= maxI', then the result is+    -- '0' (Bit 0 0), otherwise the result is '.' (Bit 1 0).+    Bit (W# (int2Word# (dataToTag# check))) 0+  where+    check = m .|. i == maxI +    sz    = natVal bv+    maxI  = (2 ^ sz) - 1+ {-# NOINLINE reduceOr# #-} {-# ANN reduceOr# hasBlackBox #-} reduceOr# :: KnownNat n => BitVector n -> Bit reduceOr# (BV 0 i) = Bit 0 (W# (int2Word# (dataToTag# check)))   where     check = i /= 0-reduceOr# bv = V.foldl (.|.) 0 (V.bv2v bv)+reduceOr# bv@(BV m i) | defI /= 0 = Bit 0 1+                      | otherwise = Bit 1 0+ where+  complementN = complementMod $ natVal bv+  defI = i .&. (complementN m)  {-# NOINLINE reduceXor# #-} {-# ANN reduceXor# hasBlackBox #-} reduceXor# :: KnownNat n => BitVector n -> Bit reduceXor# (BV 0 i) = Bit 0 (fromIntegral (popCount i `mod` 2))-reduceXor# bv = undefErrorU "reduceXor" bv+reduceXor# _ = Bit 1 0  instance Default (BitVector n) where   def = minBound#
src/Clash/Sized/Internal/Unsigned.hs view
@@ -194,7 +194,7 @@ -- width, use the functions in the 'Clash.Class.Resize.Resize' class. #if MIN_VERSION_base(4,15,0) data Unsigned (n :: Nat) =-    -- | The constructor, 'U', and the field, 'unsafeToInteger', are not+    -- | The constructor, 'U', and the field, 'unsafeToNatural', are not     -- synthesizable.     U { unsafeToNatural :: !Natural } #else
src/Clash/Sized/RTree.hs view
@@ -19,11 +19,13 @@  module Clash.Sized.RTree   ( -- * 'RTree' data type-    RTree (LR, BR)+    RTree (LR, BR, RLeaf, RBranch)     -- * Construction   , treplicate   , trepeat     -- * Accessors+  , thead+  , tlast     -- ** Indexing   , indexTree   , tindices@@ -41,6 +43,12 @@   , tfold     -- ** Specialised folds   , tdfold+    -- ** Prefix sums (scans)+    -- $scans+  , scanlPar+  , tscanl+  , scanrPar+  , tscanr     -- * Conversions   , v2t   , t2v@@ -63,13 +71,13 @@ #if MIN_VERSION_template_haskell(2,16,0) import Language.Haskell.TH.Compat #endif-import Prelude                     hiding ((++), (!!))+import Prelude                     hiding ((++), (!!), map) import Test.QuickCheck             (Arbitrary (..), CoArbitrary (..))  import Clash.Annotations.Primitive (hasBlackBox) import Clash.Class.BitPack         (BitPack (..), packXWith)-import Clash.Promoted.Nat          (SNat (..), UNat (..), pow2SNat, snatToNum,-                                    subSNat, toUNat)+import Clash.Promoted.Nat          (SNat (..), UNat (..),+                                    pow2SNat, snatToNum, subSNat, toUNat) import Clash.Promoted.Nat.Literals (d1) import Clash.Sized.Index           (Index) import Clash.Sized.Vector          (Vec (..), (!!), (++), dtfold, replace)@@ -105,26 +113,26 @@ -- * Only has elements at the leaf of the tree -- * A tree of depth /d/ has /2^d/ elements. data RTree :: Nat -> Type -> Type where-  LR_ :: a -> RTree 0 a-  BR_ :: RTree d a -> RTree d a -> RTree (d+1) a+  RLeaf :: a -> RTree 0 a+  RBranch :: RTree d a -> RTree d a -> RTree (d+1) a  instance NFData a => NFData (RTree d a) where-    rnf (LR_ x) = rnf x-    rnf (BR_ l r ) = rnf l `seq` rnf r+    rnf (RLeaf x) = rnf x+    rnf (RBranch l r ) = rnf l `seq` rnf r  textract :: RTree 0 a -> a-textract (LR_ x)   = x-textract (BR_ _ _) = error $ "textract: nodes hold no values"+textract (RLeaf x)   = x+textract (RBranch _ _) = error $ "textract: nodes hold no values" {-# NOINLINE textract #-} {-# ANN textract hasBlackBox #-}  tsplit :: RTree (d+1) a -> (RTree d a,RTree d a)-tsplit (BR_ l r) = (l,r)-tsplit (LR_ _)   = error $ "tsplit: leaf is atomic"+tsplit (RBranch l r) = (l,r)+tsplit (RLeaf _)   = error $ "tsplit: leaf is atomic" {-# NOINLINE tsplit #-} {-# ANN tsplit hasBlackBox #-} --- | Leaf of a perfect depth tree+-- | RLeaf of a perfect depth tree -- -- >>> LR 1 -- 1@@ -142,9 +150,9 @@ pattern LR :: a -> RTree 0 a pattern LR x <- (textract -> x)   where-    LR x = LR_ x+    LR x = RLeaf x --- | Branch of a perfect depth tree+-- | RBranch of a perfect depth tree -- -- >>> BR (LR 1) (LR 2) -- <1,2>@@ -162,7 +170,7 @@ pattern BR :: RTree d a -> RTree d a -> RTree (d+1) a pattern BR l r <- ((\t -> (tsplit t)) -> (l,r))   where-    BR l r = BR_ l r+    BR l r = RBranch l r  instance (KnownNat d, Eq a) => Eq (RTree d a) where   (==) t1 t2 = (==) (t2v t1) (t2v t2)@@ -171,15 +179,15 @@   compare t1 t2 = compare (t2v t1) (t2v t2)  instance Show a => Show (RTree n a) where-  showsPrec _ (LR_ a)   = shows a-  showsPrec _ (BR_ l r) = \s -> '<':shows l (',':shows r ('>':s))+  showsPrec _ (RLeaf a)   = shows a+  showsPrec _ (RBranch l r) = \s -> '<':shows l (',':shows r ('>':s))  instance ShowX a => ShowX (RTree n a) where   showsPrecX = showsPrecXWith go     where       go :: Int -> RTree d a -> ShowS-      go _ (LR_ a)   = showsX a-      go _ (BR_ l r) = \s -> '<':showsX l (',':showsX r ('>':s))+      go _ (RLeaf a)   = showsX a+      go _ (RBranch l r) = \s -> '<':showsX l (',':showsX r ('>':s))  instance KnownNat d => Functor (RTree d) where   fmap = tmap@@ -215,8 +223,8 @@   def = trepeat def  instance Lift a => Lift (RTree d a) where-  lift (LR_ a)     = [| LR_ a |]-  lift (BR_ t1 t2) = [| BR_ $(lift t1) $(lift t2) |]+  lift (RLeaf a)     = [| RLeaf a |]+  lift (RBranch t1 t2) = [| RBranch $(lift t1) $(lift t2) |] #if MIN_VERSION_template_haskell(2,16,0)   liftTyped = liftTypedFromUntyped #endif@@ -234,14 +242,14 @@   rnfX t = if isLeft (isX t) then () else go t    where     go :: RTree d a -> ()-    go (LR_ x)   = rnfX x-    go (BR_ l r) = rnfX l `seq` rnfX r+    go (RLeaf x)   = rnfX x+    go (RBranch l r) = rnfX l `seq` rnfX r    hasUndefined t = if isLeft (isX t) then True else go t    where     go :: RTree d a -> Bool-    go (LR_ x)   = hasUndefined x-    go (BR_ l r) = hasUndefined l || hasUndefined r+    go (RLeaf x)   = hasUndefined x+    go (RBranch l r) = hasUndefined l || hasUndefined r    ensureSpine = fmap ensureSpine . lazyT @@ -370,8 +378,8 @@ tdfold _ f g = go SNat   where     go :: SNat m -> RTree m a -> (p @@ m)-    go _  (LR_ a)   = f a-    go sn (BR_ l r) = let sn' = sn `subSNat` d1+    go _  (RLeaf a)   = f a+    go sn (RBranch l r) = let sn' = sn `subSNat` d1                       in  g sn' (go sn' l) (go sn' r) {-# NOINLINE tdfold #-} {-# ANN tdfold hasBlackBox #-}@@ -439,9 +447,7 @@  -- | Convert a vector with /2^d/ elements to a tree of depth /d/. ----- >>> (1:>2:>3:>4:>Nil)--- 1 :> 2 :> 3 :> 4 :> Nil--- >>> v2t (1:>2:>3:>4:>Nil)+-- >>> v2t (1 :> 2 :> 3 :> 4:> Nil) -- <<1,2>,<3,4>> v2t :: forall d a . KnownNat d => Vec (2^d) a -> RTree d a v2t = dtfold (Proxy @(V2TTree a)) LR (const BR)@@ -537,3 +543,126 @@       => RTree d a       -> RTree d a lazyT = tzipWith (flip const) (trepeat ())++-- | Extract the first element of a tree+--+-- The first element is defined to be the bottom-left leaf.+--+-- >>> thead $ BR (BR (LR 1) (LR 2)) (BR (LR 3) (LR 4))+-- 1+thead :: RTree n a -> a+thead (RLeaf x) = x+thead (RBranch x _) = thead x++-- | Extract the last element of a tree+--+-- The last element is defined to be the bottom-right leaf.+--+-- >>> tlast $ BR (BR (LR 1) (LR 2)) (BR (LR 3) (LR 4))+-- 4+tlast :: RTree n a -> a+tlast (RLeaf x) = x+tlast (RBranch _ y) = tlast y++{- $scans #scans#++Scans (`Clash.Sized.Vector.scanl`, `Clash.Sized.Vector.scanr`) are similar to+folds (`Clash.Sized.Vector.foldl`, `Clash.Sized.Vector.foldr`) but return a list+of successive reduced values. When the binary reduction operator @f@ is+associative, the scan functions in this module can be characterized as follows:++> tscanl f [x1, x2, x3, ...] == [x1, x1 `f` x2, x1 `f` x2 `f` x3, ...]++> tscanr f [..., xn2, xn1, xn] == [..., xn2 `f` xn1 `f` xn, xn1 `f` xn, xn]++The scan functions in this module provide a different trade-off between circuit+size and logic depth than the default `Clash.Sized.Vector.scanl` and+`Clash.Sized.Vector.scanr` functions. When \(n\) is the number of elements,+circuit size is \(\mathcal{O}(n \cdot \log n)\), but logic depth is \(\mathcal{O}(\log n)\).+This means the resource usage will likely increase, but the maximum clock+frequency also increases due to the reduced logic depth. The exact amount of+instantiations of @f@ given a tree of depth /d/ is:++> work 0 = 0+> work d = 2 ^ (d - 1) + 2 * work (d - 1)++-}++-- | `tscanl` applied to `Vec`+--+-- >>> scanlPar (+) (1 :> 2 :> 3 :> 4 :> Nil)+-- 1 :> 3 :> 6 :> 10 :> Nil+scanlPar ::+  KnownNat n =>+  -- | Must be associative+  (a -> a -> a) ->+  Vec (2^n) a ->+  Vec (2^n) a+scanlPar op = t2v . tscanl op . v2t+{-# INLINE scanlPar #-}++-- | `tscanr` applied to `Vec`+--+-- >>> scanrPar (+) (1 :> 2 :> 3 :> 4 :> Nil)+-- 10 :> 9 :> 7 :> 4 :> Nil+scanrPar ::+  KnownNat n =>+   -- | Must be associative+  (a -> a -> a) ->+  Vec (2^n) a ->+  Vec (2^n) a+scanrPar op = t2v . tscanr op . v2t+{-# INLINE scanrPar #-}++-- | Low-depth left scan+--+-- `tscanl` is similar to `Clash.Sized.Vector.foldl`, but returns a tree of+-- successive reduced values from the left:+--+-- > tscanl f [x1, x2, x3, ...] == [x1, x1 `f` x2, x1 `f` x2 `f` x3, ...]+--+-- >>> tscanl (+) (v2t (1 :> 2 :> 3 :> 4 :> Nil))+-- <<1,3>,<6,10>>+--+-- <<doc/scanlPar.svg>>+tscanl ::+  forall a n.+  KnownNat n =>+  -- | Must be associative+  (a -> a -> a) ->+  RTree n a ->+  RTree n a+tscanl op tr =+  case tr of+    RLeaf x -> LR x+    RBranch x y ->+      let+        x' = tscanl op x+        y' = tscanl op y+        l = tlast x'+      in BR x' (fmap (l `op`) y')++-- | Low-depth right scan+--+-- `tscanr` is similar to `Clash.Sized.Vector.foldr`, but returns a tree of+-- successive reduced values from the left:+--+-- > tscanr f [..., xn2, xn1, xn] == [..., xn2 `f` xn1 `f` xn, xn1 `f` xn, xn]+--+-- >>> tscanr (+) (v2t (1 :> 2 :> 3 :> 4 :> Nil))+-- <<10,9>,<7,4>>+tscanr ::+  forall a n.+  KnownNat n =>+  (a -> a -> a) ->+  RTree n a ->+  RTree n a+tscanr op tr =+  case tr of+    RLeaf x -> LR x+    RBranch x y ->+        let+          x' = tscanr op x+          y' = tscanr op y+          l = thead y'+        in BR (fmap (l `op`) x') y'
src/Clash/Sized/Vector.hs view
@@ -1102,9 +1102,12 @@ -- -- <<doc/scanl.svg>> ----- __NB__:+-- * __NB__: ----- > last (scanl f z xs) == foldl f z xs+--     > last (scanl f z xs) == foldl f z xs+--+-- * For a different trade-off between circuit size and logic depth for+-- associative operators, see "Clash.Sized.RTree#scans" scanl :: (b -> a -> b) -> b -> Vec n a -> Vec (n + 1) b scanl f z xs = ws   where@@ -1137,9 +1140,12 @@ -- -- <<doc/scanr.svg>> ----- __NB__:+-- * __NB__: ----- > head (scanr f z xs) == foldr f z xs+--     > head (scanr f z xs) == foldr f z xs+--+-- * For a different trade-off between circuit size and logic depth for+-- associative operators, see "Clash.Sized.RTree#scans" scanr :: (a -> b -> b) -> b -> Vec n a -> Vec (n + 1) b scanr f z xs = ws   where
src/Clash/Tutorial.hs view
@@ -3,6 +3,7 @@               2017-2019, Myrtle Software Ltd               2017     , QBayLogic, Google Inc.,               2021     , QBayLogic B.V.+              2022     , LUMI GUIDE FIETSDETECTIE B.V.  Licence   : Creative Commons 4.0 (CC BY 4.0) (https://creativecommons.org/licenses/by/4.0/) Maintainer:  QBayLogic B.V. <devops@qbaylogic.com>@@ -1247,11 +1248,15 @@ * @~IF \<CONDITION\> ~THEN \<THEN\> ~ELSE \<ELSE\> ~FI@: renders the @\<ELSE\>@   part when @\<CONDITION\>@ evaluates to /0/, and renders the @\<THEN\>@ in all   other cases. Valid @\<CONDITION\>@s are @~LENGTH[\<HOLE\>]@, @~SIZE[\<HOLE\>]@,+  @~CMPLE[\<HOLE1\>][\<HOLE2\>]@,   @~DEPTH[\<HOLE\>]@, @~VIVADO@, @~IW64@, @~ISLIT[N]@, @~ISVAR[N]@, @~ISACTIVEENABLE[N]@,   @~ISSYNC[N]@, and @~AND[\<HOLE1\>,\<HOLE2\>,..]@. * @~VIVADO@: /1/ when Clash compiler is invoked with the @-fclash-xilinx@ or   @-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.+  /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@).   The @\<TYPE\>@ hole indicates the type of the expression and must be either@@ -1261,7 +1266,7 @@   is converted to type indicated by @\<TYPE\>@. The @\<TYPE\>@ hole must be   either @~TYP[N]@, @~TYPO@, or @~TYPEL[\<HOLE\>]@. * @~INCLUDENAME[N]@: the generated name of the @N@'th included component.-* @~FILEPATH[\<HOLE\>]@: The argument mentioned in @\<HOLE\>@ is a file which+* @~FILE[\<HOLE\>]@: The argument mentioned in @\<HOLE\>@ is a file which   must be copied to the location of the generated HDL. * @~GENERATE@: Verilog: create a /generate/ statement, except when already in   a /generate/ context.@@ -1270,13 +1275,16 @@ * @~ISLIT[N]@: Is the @(N+1)@'th argument to the function a literal. * @~ISVAR[N]@: Is the @(N+1)@'th argument to the function explicitly not a   literal.+* @~ISSCALAR[N]@: Is the @(N+1)@'th argument to the function a scalar. Note+  that this means different things for different HDLs. In (System)Verilog only+  @Bit@ and @Bool@ are considered scalar. In VHDL, in addition to those two,+  enumeration types and integers are considered scalar. * @~TAG[N]@: Name of given domain. Errors when called on an argument which is not   a 'KnownDomain', 'Reset', or 'Clock'. * @~PERIOD[N]@: Clock period of given domain. Errors when called on an argument   which is not a 'KnownDomain' or 'KnownConf'. * @~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-  @~ISGATED@. Errors when called on an argument which is not a signal of bools. * @~ISSYNC[N]@: Does synthesis domain at the @(N+1)@'th argument have synchronous resets. Errors   when called on an argument which is not a 'KnownDomain' or 'KnownConf'. * @~ISINITDEFINED[N]@: Does synthesis domain at the @(N+1)@'th argument have defined initial@@ -1286,6 +1294,7 @@   argument which is not a '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. * @~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
src/Clash/XException.hs view
@@ -53,6 +53,11 @@ import           Data.Complex        (Complex) import           Data.Either         (isLeft) import           Data.Foldable       (toList)+import           Data.Functor.Compose (Compose)+import           Data.Functor.Const  (Const)+import           Data.Functor.Identity (Identity)+import           Data.Functor.Product (Product)+import           Data.Functor.Sum    (Sum) import           Data.Int            (Int8, Int16, Int32, Int64) import           Data.Ord            (Down (Down)) import           Data.Ratio          (Ratio, numerator, denominator)@@ -369,6 +374,11 @@ printX x = putStrLn $ showX x  instance ShowX ()+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)+instance (ShowX (f a), ShowX (g a)) => ShowX (Sum f g a)+instance (ShowX (f (g a))) => ShowX (Compose f g a)  instance {-# OVERLAPPABLE #-} ShowX a => ShowX [a] where   showsPrecX _ = showListX@@ -532,6 +542,11 @@ instance NFDataX a => NFDataX [a] instance (NFDataX a, NFDataX b) => NFDataX (Either a b) instance NFDataX a => NFDataX (Maybe 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)+instance (NFDataX (f a), NFDataX (g a)) => NFDataX (Sum f g a)+instance (NFDataX (f (g a))) => NFDataX (Compose f g a)  instance NFDataX Char where   deepErrorX = errorX
tests/Clash/Tests/DerivingDataRepr.hs view
@@ -10,17 +10,17 @@ import Prelude ((=<<), ($)) import Clash.Annotations.BitRepresentation import Clash.Annotations.BitRepresentation.Deriving-import Clash.Tests.DerivingDataReprTypes (Train(..), RGB(..))+import Clash.Tests.DerivingDataReprTypes (Train(..), RGB(..), Headphones(..), EarCup(..)) import Data.Maybe (Maybe(..))  --------------------------------------------------------- ------------ DERIVING SIMPLE REPRESENTATIONS ------------ ----------------------------------------------------------oneHotOverlapRepr :: DataReprAnn-oneHotOverlapRepr = $( (simpleDerivator OneHot OverlapL) =<< [t| Train |] )+oneHotOverlapLRepr :: DataReprAnn+oneHotOverlapLRepr = $( (simpleDerivator OneHot OverlapL) =<< [t| Train |] ) -oneHotOverlapRepr' :: DataReprAnn-oneHotOverlapRepr' =+oneHotOverlapLRepr' :: DataReprAnn+oneHotOverlapLRepr' =   DataReprAnn     $(liftQ [t| Train |])     8@@ -30,6 +30,43 @@     , ConstrRepr 'Toy         128 128 []     ] +oneHotOverlapRRepr :: DataReprAnn+oneHotOverlapRRepr = $( (simpleDerivator OneHot OverlapR) =<< [t| Train |] )++oneHotOverlapRRepr' :: DataReprAnn+oneHotOverlapRRepr' =+  DataReprAnn+    $(liftQ [t| Train |])+    8+    [ ConstrRepr 'Passenger   16  16  [0b0011]+    , ConstrRepr 'Freight     32  32  [0b1100, 0b0011]+    , ConstrRepr 'Maintenance 64  64  []+    , ConstrRepr 'Toy         128 128 []+    ]++oneHotOverlapReprRec :: DataReprAnn+oneHotOverlapReprRec = $( (simpleDerivator OneHot OverlapL) =<< [t| Headphones |] )++oneHotOverlapReprRec' :: DataReprAnn+oneHotOverlapReprRec' =+  DataReprAnn+    $(liftQ [t| Headphones |])+    4+    [ ConstrRepr 'InEar   4  4  [0b10]+    , ConstrRepr 'OverEar 8  8  [0b11]+    ]++oneHotOverlapReprInfix :: DataReprAnn+oneHotOverlapReprInfix = $( (simpleDerivator OneHot OverlapL) =<< [t| EarCup |] )++oneHotOverlapReprInfix' :: DataReprAnn+oneHotOverlapReprInfix' =+  DataReprAnn+    $(liftQ [t| EarCup |])+    5+    [ ConstrRepr '(:<>:) 16  16  [0b1100,0b0011] ]++ oneHotWideRepr :: DataReprAnn oneHotWideRepr = $( (simpleDerivator OneHot Wide) =<< [t| Train |] ) @@ -109,10 +146,13 @@ -- MAIN tests :: TestTree tests = testGroup "DerivingDataRepr"-  [ testCase "OneHotOverlap" $ oneHotOverlapRepr @?= oneHotOverlapRepr'-  , testCase "OneHotWide"    $ oneHotWideRepr    @?= oneHotWideRepr'-  , testCase "BinaryOverlap" $ countOverlapRepr  @?= countOverlapRepr'-  , testCase "BinaryWide"    $ countWideRepr     @?= countWideRepr'-  , testCase "Packed"        $ packedRepr        @?= packedRepr'-  , testCase "PackedMaybe"   $ packedMaybeRGB    @?= packedMaybeRGB'+  [ testCase "OneHotOverlapL"     $ oneHotOverlapLRepr     @?= oneHotOverlapLRepr'+  , testCase "OneHotOverlapR"     $ oneHotOverlapRRepr     @?= oneHotOverlapRRepr'+  , testCase "OneHotOverlapRec"   $ oneHotOverlapReprRec   @?= oneHotOverlapReprRec'+  , testCase "OneHotOverlapInfix" $ oneHotOverlapReprInfix @?= oneHotOverlapReprInfix'+  , testCase "OneHotWide"         $ oneHotWideRepr         @?= oneHotWideRepr'+  , testCase "BinaryOverlap"      $ countOverlapRepr       @?= countOverlapRepr'+  , testCase "BinaryWide"         $ countWideRepr          @?= countWideRepr'+  , testCase "Packed"             $ packedRepr             @?= packedRepr'+  , testCase "PackedMaybe"        $ packedMaybeRGB         @?= packedMaybeRGB'   ]
tests/Clash/Tests/DerivingDataReprTypes.hs view
@@ -29,3 +29,11 @@  deriveDefaultAnnotation [t| RGB |] deriveBitPack [t| RGB |]++data Headphones+  = InEar+      { _wireless :: Bool }+  | OverEar+      { _impedance :: SmallInt }++data EarCup = SmallInt :<>: SmallInt