clash-prelude 0.5.0.1 → 0.5.1
raw patch · 11 files changed
+238/−187 lines, 11 files
Files
- CHANGELOG.md +13/−1
- clash-prelude.cabal +1/−1
- src/CLaSH/Prelude.hs +29/−26
- src/CLaSH/Prelude/Explicit.hs +34/−29
- src/CLaSH/Signal/Explicit.hs +33/−53
- src/CLaSH/Signal/Implicit.hs +30/−54
- src/CLaSH/Sized/Fixed.hs +1/−1
- src/CLaSH/Sized/Signed.hs +18/−0
- src/CLaSH/Sized/Unsigned.hs +17/−0
- src/CLaSH/Sized/Vector.hs +60/−16
- src/CLaSH/Tutorial.hs +2/−6
CHANGELOG.md view
@@ -1,7 +1,19 @@ # Changelog for [`clash-prelude` package](http://hackage.haskell.org/package/clash-prelude) +## 0.5.1 *June 5th 2014*++* New features:+ * Add `Default` instance for `Vec` [#2](https://github.com/christiaanb/clash-prelude/issues/2)+ * Instantiation for `blockRam` [#3](https://github.com/christiaanb/clash-prelude/issues/2)++* Fixes bugs:+ * Fixed error on documentation of fLit in Fixed.hs [#6](https://github.com/christiaanb/clash-prelude/issues/6)+ * Non-translatable `Enum` function interfere with `sassert` compilation [#7](https://github.com/christiaanb/clash-prelude/issues/7)+ * Substituted the word 'list' into 'vector' in some places in the documentation. [#8](https://github.com/christiaanb/clash-prelude/issues/8)+ * mark vselectI INLINEABLE [#10](https://github.com/christiaanb/clash-prelude/issues/10)+ ## 0.5 *April 3rd 2014*- * Add explicitly clocked synchronous signals for multi-clock circuits+ * Add explicitly clocked synchronous signals for multi-clock circuits ## 0.4.1 *March 27th 2014* * Add saturation to fixed-point operators
clash-prelude.cabal view
@@ -1,5 +1,5 @@ Name: clash-prelude-Version: 0.5.0.1+Version: 0.5.1 Synopsis: CAES Language for Synchronous Hardware - Prelude library Description: CλaSH (pronounced ‘clash’) is a functional hardware description language that
src/CLaSH/Prelude.hs view
@@ -182,24 +182,21 @@ {-# NOINLINE blockRam #-} -- | Create a blockRAM with space for @n@ elements. ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > bram40 :: Signal (Unsigned 6) -> Signal (Unsigned 6) -> Signal Bool -> Signal a -> Signal a--- > bram40 = blockRam d40-blockRam :: forall n m a . (KnownNat n, KnownNat m, Pack a, Default a)- => SNat n -- ^ Size @n@ of the blockram+-- > bram40 :: Signal (Unsigned 6) -> Signal (Unsigned 6) -> Signal Bool -> Signal Bit -> Signal Bit+-- > bram40 = blockRam (vcopy d40 H)+blockRam :: (Pack a, KnownNat n, KnownNat m)+ => Vec n a -- ^ Initial content of the BRAM, also determines the size ,@n@, of the BRAM.+ -- NB: *MUST* be a constant. -> Signal (Unsigned m) -- ^ Write address @w@ -> Signal (Unsigned m) -- ^ Read address @r@ -> Signal Bool -- ^ Write enable -> Signal a -- ^ Value to write (at address @w@) -> Signal a -- ^ Value of the 'blockRAM' at address @r@ from the previous clock cycle-blockRam n wr rd en din = pack $ (bram' <^> binit) (wr,rd,en,din)+blockRam binit wr rd en din = pack $ (bram' <^> (binit,undefined)) (wr,rd,en,din) where- binit :: (Vec n a,a)- binit = (vcopy n def,def)-- bram' :: (Vec n a,a) -> (Unsigned m, Unsigned m, Bool, a)- -> (((Vec n a),a),a) bram' (ram,o) (w,r,e,d) = ((ram',o'),o) where ram' | e = vreplace ram w d@@ -209,24 +206,28 @@ {-# DEPRECATED blockRamC "'Comp' is deprecated and will be removed in version 0.6, use 'blockRam' instead" #-} -- | Create a blockRAM with space for @n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > bramC40 :: Comp (Unsigned 6, Unsigned 6, Bool, a) a--- > bramC40 = blockRamC d40-blockRamC :: (KnownNat n, KnownNat m, Pack a, Default a)- => SNat n -- ^ Size @n@ of the blockram+-- > bramC40 :: Comp (Unsigned 6, Unsigned 6, Bool, Bit) Bit+-- > bramC40 = blockRamC (vcopy d40 H)+blockRamC :: (KnownNat n, KnownNat m, Pack a)+ => Vec n a -- ^ Initial content of the BRAM, also determines the size ,@n@, of the BRAM.+ -- NB: *MUST* be a constant. -> Comp (Unsigned m, Unsigned m, Bool, a) a blockRamC n = C ((\(wr,rd,en,din) -> blockRam n wr rd en din) Prelude.. unpack) {-# INLINABLE blockRamPow2 #-} -- | Create a blockRAM with space for 2^@n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > bram32 :: Signal (Unsigned 5) -> Signal (Unsigned 5) -> Signal Bool -> Signal a -> Signal a--- > bram32 = blockRamPow2 d32-blockRamPow2 :: (KnownNat n, KnownNat (2^n), Pack a, Default a)- => SNat (2^n) -- ^ Size @2^n@ of the blockram+-- > bram32 :: Signal (Unsigned 5) -> Signal (Unsigned 5) -> Signal Bool -> Signal Bit -> Signal Bit+-- > bram32 = blockRamPow2 (vcopy d32 H)+blockRamPow2 :: (KnownNat (2^n), KnownNat n, Pack a)+ => Vec (2^n) a -- ^ Initial content of the BRAM, also determines the size ,@2^n@, of the BRAM.+ -- NB: *MUST* be a constant. -> Signal (Unsigned n) -- ^ Write address @w@ -> Signal (Unsigned n) -- ^ Read address @r@ -> Signal Bool -- ^ Write enable@@ -237,12 +238,14 @@ {-# DEPRECATED blockRamPow2C "'Comp' is deprecated and will be removed in version 0.6, use 'blockRamPow2' instead" #-} -- | Create a blockRAM with space for 2^@n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > bramC32 :: Comp (Unsigned 5, Unsigned 5, Bool, a) a--- > bramC32 = blockRamPow2C d32-blockRamPow2C :: (KnownNat n, KnownNat (2^n), Pack a, Default a)- => SNat (2^n) -- ^ Size @2^n@ of the blockram+-- > bramC32 :: Comp (Unsigned 5, Unsigned 5, Bool, Bit) Bit+-- > bramC32 = blockRamPow2C (vcopy d32 H)+blockRamPow2C :: (KnownNat (2^n), KnownNat n, Pack a)+ => Vec (2^n) a -- ^ Initial content of the BRAM, also determines the size ,@2^n@, of the BRAM.+ -- NB: *MUST* be a constant. -> Comp (Unsigned n, Unsigned n, Bool, a) a blockRamPow2C n = C ((\(wr,rd,en,din) -> blockRamPow2 n wr rd en din) Prelude.. unpack)
src/CLaSH/Prelude/Explicit.hs view
@@ -49,10 +49,10 @@ import Control.Category as Category import GHC.TypeLits (KnownNat,type (^), type (+)) -import CLaSH.Promoted.Nat (SNat, snat)+import CLaSH.Promoted.Nat (snat) import CLaSH.Signal.Explicit import CLaSH.Sized.Unsigned (Unsigned)-import CLaSH.Sized.Vector (Vec (..), (!), (+>>), maxIndex, vcopy, vcopyI, vreplace)+import CLaSH.Sized.Vector (Vec (..), (!), (+>>), maxIndex, vcopyI, vreplace) {-# INLINABLE sync #-} -- | Create a synchronous function from a combinational function describing@@ -187,28 +187,25 @@ {-# NOINLINE cblockRam #-} -- | Create a blockRAM with space for @n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` -- -- > clk100 = Clock d100 -- > -- > bram40 :: CSignal 100 (Unsigned 6) -> CSignal 100 (Unsigned 6)--- > -> CSignal 100 Bool -> CSignal 100 a -> 100 CSignal a--- > bram40 = cblockRam clk100 d40-cblockRam :: forall n m a clk . (KnownNat n, KnownNat m, CPack a, Default a)+-- > -> CSignal 100 Bool -> CSignal 100 Bit -> 100 CSignal Bit+-- > bram40 = cblockRam clk100 (vcopy d40 H)+cblockRam :: (CPack a, KnownNat n, KnownNat m) => Clock clk -- ^ 'Clock' to synchronize to- -> SNat n -- ^ Size @n@ of the blockram+ -> Vec n a -- ^ Initial content of the BRAM, also determines the size ,@n@, of the BRAM.+ -- NB: *MUST* be a constant. -> CSignal clk (Unsigned m) -- ^ Write address @w@ -> CSignal clk (Unsigned m) -- ^ Read address @r@ -> CSignal clk Bool -- ^ Write enable -> CSignal clk a -- ^ Value to write (at address @w@) -> CSignal clk a -- ^ Value of the 'blockRAM' at address @r@ from the previous clock cycle-cblockRam clk n wr rd en din = cpack clk $ (sync clk bram' binit) (wr,rd,en,din)+cblockRam clk binit wr rd en din = cpack clk $ (sync clk bram' (binit,undefined)) (wr,rd,en,din) where- binit :: (Vec n a,a)- binit = (vcopy n def,def)-- bram' :: (Vec n a,a) -> (Unsigned m, Unsigned m, Bool, a)- -> (((Vec n a),a),a) bram' (ram,o) (w,r,e,d) = ((ram',o'),o) where ram' | e = vreplace ram w d@@ -218,28 +215,34 @@ {-# DEPRECATED blockRamCC "'CComp' is deprecated and will be removed in version 0.6, use 'cblockRam' instead" #-} -- | Create a blockRAM with space for @n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > clk100 = Clock 100+-- > clk100 = Clock d100 -- >--- > bramC40 :: CComp 100 (Unsigned 6, Unsigned 6, Bool, a) a--- > bramC40 = blockRamCC clk100 d40+-- > bramC40 :: CComp 100 (Unsigned 6, Unsigned 6, Bool, Bit) Bit+-- > bramC40 = blockRamCC clk100 (vcopy d40 H) blockRamCC :: (KnownNat n, KnownNat m, CPack a, Default a) => Clock clk -- ^ 'Clock' to synchronize to- -> SNat n -- ^ Size @n@ of the blockram+ -> Vec n a -- ^ Initial content of the BRAM, also determines the size ,@n@, of the BRAM.+ -- NB: *MUST* be a constant. -> CComp clk (Unsigned m, Unsigned m, Bool, a) a blockRamCC clk n = CC ((\(wr,rd,en,din) -> cblockRam clk n wr rd en din) Prelude.. cunpack clk) {-# INLINABLE cblockRamPow2 #-} -- | Create a blockRAM with space for 2^@n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` ----- > bram32 :: Signal (Unsigned 5) -> Signal (Unsigned 5) -> Signal Bool -> Signal a -> Signal a--- > bram32 = cblockRamPow2 d32-cblockRamPow2 :: (KnownNat n, KnownNat (2^n), CPack a, Default a)+-- > clk100 = Clock d100+-- >+-- > bramC32 :: CSignal 100 (Unsigned 5) -> CSignal 100 (Unsigned 5) -> CSignal 100 Bool -> CSignal 100 Bit -> CSignal 100 Bit+-- > bramC32 = cblockRamPow2 clk100 (vcopy d32 H)+cblockRamPow2 :: (KnownNat n, KnownNat (2^n), CPack a) => Clock clk -- ^ 'Clock' to synchronize to- -> SNat (2^n) -- ^ Size @2^n@ of the blockram+ -> Vec (2^n) a -- ^ Initial content of the BRAM, also determines the size ,@2^n@, of the BRAM.+ -- NB: *MUST* be a constant. -> CSignal clk (Unsigned n) -- ^ Write address @w@ -> CSignal clk (Unsigned n) -- ^ Read address @r@ -> CSignal clk Bool -- ^ Write enable@@ -250,15 +253,17 @@ {-# DEPRECATED blockRamPow2CC "'CComp' is deprecated and will be removed in version 0.6, use 'cblockRamPow2' instead" #-} -- | Create a blockRAM with space for 2^@n@ elements ----- NB: Read value is delayed by 1 cycle+-- * NB: Read value is delayed by 1 cycle+-- * NB: Initial output value is `undefined` -- -- > clk100 = Clock d100 -- >--- > bramC32 :: CComp 100 (Unsigned 5, Unsigned 5, Bool, a) a--- > bramC32 = blockRamPow2CC clk100 d32-blockRamPow2CC :: (KnownNat n, KnownNat (2^n), CPack a, Default a)- => Clock clk -- ^ 'Clock' to synchronize to- -> SNat (2^n) -- ^ Size @2^n@ of the blockram+-- > bramC32 :: CComp 100 (Unsigned 5, Unsigned 5, Bool, Bit) Bit+-- > bramC32 = blockRamPow2CC clk100 (vcopy d32 Bit)+blockRamPow2CC :: (KnownNat n, KnownNat (2^n), CPack a)+ => Clock clk -- ^ 'Clock' to synchronize to+ -> Vec (2^n) a -- ^ Initial content of the BRAM, also determines the size ,@2^n@, of the BRAM.+ -- NB: *MUST* be a constant. -> CComp clk (Unsigned n, Unsigned n, Bool, a) a blockRamPow2CC clk n = CC ((\(wr,rd,en,din) -> cblockRamPow2 clk n wr rd en din) Prelude.. cunpack clk)
src/CLaSH/Signal/Explicit.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE DefaultSignatures #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}@@ -27,7 +28,7 @@ ) where -import Data.Coerce+import Data.Coerce (coerce) import Control.Applicative (Applicative (..), (<$>), liftA2) import GHC.TypeLits (Nat) @@ -133,6 +134,9 @@ -- -- > cpack :: Clock clk -> CSignal clk Bit -> CSignal clk Bit cpack :: Clock clk -> CSignalP clk a -> CSignal clk a++ default cpack :: Clock clk -> CSignal clk a -> CSignal clk a+ cpack _ s = s -- | Example: -- -- > cunpack :: Clock clk -> CSignal clk (a,b) -> (CSignal clk a, CSignal clk b)@@ -142,59 +146,21 @@ -- > cunpack :: Clock clk -> CSignal clk Bit -> CSignal clk Bit cunpack :: Clock clk -> CSignal clk a -> CSignalP clk a --- | Simulate a (@'CSignalP' clk1 a -> 'CSignalP' clk2 b@) function given a list--- of samples of type @a@------ > clk100 = Clock d100------ >>> csimulateP clk100 clk100 (cunpack clk100 . cregister clk100 (8,8) . cpack clk100) [(1,1), (2,2), (3,3), ...--- [(8,8), (1,1), (2,2), (3,3), ...-csimulateP :: (CPack a, CPack b)- => Clock clk1 -- ^ 'Clock' of the incoming signal- -> Clock clk2 -- ^ 'Clock' of the outgoing signal- -> (CSignalP clk1 a -> CSignalP clk2 b) -- ^ Function to simulate- -> [a] -> [b]-csimulateP clk1 clk2 f = csimulate (cpack clk2 . f . cunpack clk1)--instance CPack Bit where- cpack _ = id- cunpack _ = id--instance CPack (Signed n) where- cpack _ = id- cunpack _ = id--instance CPack (Unsigned n) where- cpack _ = id- cunpack _ = id--instance CPack (Fixed frac rep size) where- cpack _ = id- cunpack _ = id--instance CPack Bool where- cpack _ = id- cunpack _ = id--instance CPack Integer where- cpack _ = id- cunpack _ = id--instance CPack Int where- cpack _ = id- cunpack _ = id--instance CPack Float where- cpack _ = id- cunpack _ = id--instance CPack Double where- cpack _ = id- cunpack _ = id+ default cunpack :: Clock clk -> CSignal clk a -> CSignal clk a+ cunpack _ s = s -instance CPack () where- cpack _ = id- cunpack _ = id+instance CPack Bit+instance CPack (Signed n)+instance CPack (Unsigned n)+instance CPack (Fixed frac rep size)+instance CPack Bool+instance CPack Integer+instance CPack Int+instance CPack Float+instance CPack Double+instance CPack ()+instance CPack (Maybe a)+instance CPack (Either a b) instance CPack (a,b) where type CSignalP t (a,b) = (CSignal t a, CSignal t b)@@ -269,6 +235,20 @@ cpack clk vs = mkCSignal (vmap (shead . coerce) vs) (cpack clk (vmap cstail vs)) cunpack _ (CSignal (Nil :- _)) = Nil cunpack clk vs@(CSignal ((_ :> _) :- _)) = fmap vhead vs :> cunpack clk (fmap vtail vs)++-- | Simulate a (@'CSignalP' clk1 a -> 'CSignalP' clk2 b@) function given a list+-- of samples of type @a@+--+-- > clk100 = Clock d100+--+-- >>> csimulateP clk100 clk100 (cunpack clk100 . cregister clk100 (8,8) . cpack clk100) [(1,1), (2,2), (3,3), ...+-- [(8,8), (1,1), (2,2), (3,3), ...+csimulateP :: (CPack a, CPack b)+ => Clock clk1 -- ^ 'Clock' of the incoming signal+ -> Clock clk2 -- ^ 'Clock' of the outgoing signal+ -> (CSignalP clk1 a -> CSignalP clk2 b) -- ^ Function to simulate+ -> [a] -> [b]+csimulateP clk1 clk2 f = csimulate (cpack clk2 . f . cunpack clk1) -- | Synchronisation function that is basically a represented by a (bundle of) -- wire(s) in hardware. This function should only be used as part of a proper
src/CLaSH/Signal/Implicit.hs view
@@ -1,5 +1,6 @@-{-# LANGUAGE LambdaCase #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DefaultSignatures #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE TypeFamilies #-} module CLaSH.Signal.Implicit ( -- * Implicitly clocked synchronous signal@@ -19,9 +20,10 @@ ) where -import Control.Applicative+import Control.Applicative (Applicative (..), (<$>), liftA2) import CLaSH.Bit (Bit)+import CLaSH.Sized.Fixed (Fixed) import CLaSH.Sized.Signed (Signed) import CLaSH.Sized.Unsigned (Unsigned) import CLaSH.Sized.Vector (Vec(..), vmap, vhead, vtail)@@ -89,6 +91,7 @@ -- @ class Pack a where type SignalP a+ type SignalP a = Signal a -- | Example: -- -- > pack :: (Signal a, Signal b) -> Signal (a,b)@@ -97,6 +100,9 @@ -- -- > pack :: Signal Bit -> Signal Bit pack :: SignalP a -> Signal a++ default pack :: Signal a -> Signal a+ pack s = s -- | Example: -- -- > unpack :: Signal (a,b) -> (Signal a, Signal b)@@ -106,58 +112,21 @@ -- > unpack :: Signal Bit -> Signal Bit unpack :: Signal a -> SignalP a --- | Simulate a (@'SignalP' a -> 'SignalP' b@) function given a list of samples--- of type @a@------ >>> simulateP (unpack . register (8,8) . pack) [(1,1), (2,2), (3,3), ...--- [(8,8), (1,1), (2,2), (3,3), ...-simulateP :: (Pack a, Pack b) => (SignalP a -> SignalP b) -> [a] -> [b]-simulateP f = simulate (pack . f . unpack)--instance Pack Bit where- type SignalP Bit = Signal Bit- pack = id- unpack = id--instance Pack (Signed n) where- type SignalP (Signed n) = Signal (Signed n)- pack = id- unpack = id--instance Pack (Unsigned n) where- type SignalP (Unsigned n) = Signal (Unsigned n)- pack = id- unpack = id--instance Pack Bool where- type SignalP Bool = Signal Bool- pack = id- unpack = id--instance Pack Integer where- type SignalP Integer = Signal Integer- pack = id- unpack = id--instance Pack Int where- type SignalP Int = Signal Int- pack = id- unpack = id--instance Pack Float where- type SignalP Float = Signal Float- pack = id- unpack = id--instance Pack Double where- type SignalP Double = Signal Double- pack = id- unpack = id+ default unpack :: Signal a -> Signal a+ unpack s = s -instance Pack () where- type SignalP () = Signal ()- pack = id- unpack = id+instance Pack Bit+instance Pack (Signed n)+instance Pack (Unsigned n)+instance Pack (Fixed frac rep size)+instance Pack Bool+instance Pack Integer+instance Pack Int+instance Pack Float+instance Pack Double+instance Pack ()+instance Pack (Maybe a)+instance Pack (Either a b) instance Pack (a,b) where type SignalP (a,b) = (Signal a, Signal b)@@ -233,6 +202,13 @@ unpack (Nil :- _) = Nil unpack vs@((_ :> _) :- _) = fmap vhead vs :> (unpack (fmap vtail vs)) +-- | Simulate a (@'SignalP' a -> 'SignalP' b@) function given a list of samples+-- of type @a@+--+-- >>> simulateP (unpack . register (8,8) . pack) [(1,1), (2,2), (3,3), ...+-- [(8,8), (1,1), (2,2), (3,3), ...+simulateP :: (Pack a, Pack b) => (SignalP a -> SignalP b) -> [a] -> [b]+simulateP f = simulate (pack . f . unpack) -- | Operator lifting, use in conjunction with ('^>') --
src/CLaSH/Sized/Fixed.hs view
@@ -494,7 +494,7 @@ -- -- So when you type: ----- > n = $$(fLit 2.2867) :: SFixed 4 4+-- > n = $$(fLit 2.8672) :: SFixed 4 4 -- -- The compiler sees: --
src/CLaSH/Sized/Signed.hs view
@@ -66,6 +66,24 @@ pred = minS (fromIntegerS 1) toEnum = fromIntegerS . toInteger fromEnum = fromEnum . toIntegerS+ enumFrom = enumFromS+ enumFromThen = enumFromThenS+ enumFromTo = enumFromToS+ enumFromThenTo = enumFromThenToS++{-# NOINLINE enumFromS #-}+{-# NOINLINE enumFromThenS #-}+{-# NOINLINE enumFromToS #-}+{-# NOINLINE enumFromThenToS #-}+enumFromS :: KnownNat n => Signed n -> [Signed n]+enumFromThenS :: KnownNat n => Signed n -> Signed n -> [Signed n]+enumFromToS :: KnownNat n => Signed n -> Signed n -> [Signed n]+enumFromThenToS :: KnownNat n => Signed n -> Signed n -> Signed n -> [Signed n]+enumFromS x = map toEnum [fromEnum x ..]+enumFromThenS x y = map toEnum [fromEnum x, fromEnum y ..]+enumFromToS x y = map toEnum [fromEnum x .. fromEnum y]+enumFromThenToS x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y]+ instance KnownNat n => Bounded (Signed n) where minBound = minBoundS
src/CLaSH/Sized/Unsigned.hs view
@@ -64,6 +64,23 @@ pred = minU (fromIntegerU 1) toEnum = fromIntegerU . toInteger fromEnum = fromEnum . toIntegerU+ enumFrom = enumFromU+ enumFromThen = enumFromThenU+ enumFromTo = enumFromToU+ enumFromThenTo = enumFromThenToU++{-# NOINLINE enumFromU #-}+{-# NOINLINE enumFromThenU #-}+{-# NOINLINE enumFromToU #-}+{-# NOINLINE enumFromThenToU #-}+enumFromU :: KnownNat n => Unsigned n -> [Unsigned n]+enumFromThenU :: KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]+enumFromToU :: KnownNat n => Unsigned n -> Unsigned n -> [Unsigned n]+enumFromThenToU :: KnownNat n => Unsigned n -> Unsigned n -> Unsigned n -> [Unsigned n]+enumFromU x = map toEnum [fromEnum x ..]+enumFromThenU x y = map toEnum [fromEnum x, fromEnum y ..]+enumFromToU x y = map toEnum [fromEnum x .. fromEnum y]+enumFromThenToU x1 x2 y = map toEnum [fromEnum x1, fromEnum x2 .. fromEnum y] instance KnownNat n => Bounded (Unsigned n) where minBound = fromIntegerU 0
src/CLaSH/Sized/Vector.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} @@ -23,6 +24,8 @@ -- ** Applying functions to 'Vec'tor elements , vmap, vzipWith , vfoldr, vfoldl, vfoldr1, vfoldl1+ , vscanl, vscanr, vscanl1, vscanr1+ , vmapAccumL, vmapAccumR -- ** Indexing 'Vec'tors , (!), vreplace, maxIndex, vlength -- ** Generating 'Vec'tors@@ -36,6 +39,7 @@ import Control.Applicative -- import Data.Traversable+import Data.Default import Data.Foldable hiding (toList) import Data.Proxy import GHC.TypeLits@@ -48,8 +52,8 @@ -- | Fixed size vectors -- -- * Lists with their length encoded in their type--- * 'Vec'tor elements have a descending subscript starting from 'maxIndex' ('vlength' - 1)--- and ending at 0+-- * 'Vec'tor elements have a DESCENDING subscript starting from 'maxIndex'+-- ('vlength' - 1) and ending at 0 -- -- >>> (3:>4:>5:>Nil) -- <3,4,5>@@ -86,6 +90,9 @@ instance Functor (Vec n) where fmap = vmap +instance (Default a, KnownNat n) => Default (Vec n a) where+ def = vcopyI def+ {-# NOINLINE vhead #-} -- | Extract the first element of a vector --@@ -284,7 +291,7 @@ vmerge (x :> xs) (y :> ys) = unsafeCoerce (x :> y :> (vmerge xs (unsafeCoerce ys))) {-# NOINLINE vreverse #-}--- | Returns the elements in a list in reverse order+-- | Returns the elements in a vector in reverse order -- -- >>> vreverse (1:>2:>3:>4:>Nil) -- <4,3,2,1>@@ -293,7 +300,7 @@ vreverse (x :> xs) = vreverse xs <: x {-# NOINLINE vmap #-}--- | 'vmap' @f xs@ is the list obtained by applying @f@ to each element+-- | 'vmap' @f xs@ is the vector obtained by applying @f@ to each element -- of @xs@, i.e., -- -- > vmap f (xn :> ... :> x2 :> x1 :> Nil) == (f xn :> ... :> f x2 :> f x1 :> Nil)@@ -355,25 +362,62 @@ vfoldl1 :: (a -> a -> a) -> Vec (n + 1) a -> a vfoldl1 f xs = vfoldl f (vhead xs) (vtail xs) -{-# NOINLINE vzip #-}--- | 'vzip' takes two lists and returns a list of corresponding pairs.+{-# INLINEABLE vscanl #-}+vscanl :: KnownNat n => (b -> a -> b) -> b -> Vec n a -> Vec (n + 1) b+vscanl f z xs = ws+ where+ ws = z :> vzipWith f (lazyV (vinit ws)) xs++{-# INLINEABLE vscanl1 #-}+vscanl1 :: KnownNat n => (a -> a -> a) -> Vec n a -> Vec n a+vscanl1 f xs = vinit (vscanl f (vhead xs') (vtail xs'))+ where+ xs' = xs <: undefined++{-# INLINEABLE vscanr #-}+vscanr :: KnownNat n => (a -> b -> b) -> b -> Vec n a -> Vec (n + 1) b+vscanr f z xs = ws+ where+ ws = vzipWith f xs (lazyV (vtail ws)) <: z++{-# INLINEABLE vscanr1 #-}+vscanr1 :: KnownNat n => (a -> a -> a) -> Vec n a -> Vec n a+vscanr1 f xs = vtail (vscanr f (vlast xs') (vinit xs'))+ where+ xs' = undefined :> xs++{-# INLINEABLE vmapAccumL #-}+vmapAccumL :: KnownNat n => (acc -> x -> (acc,y)) -> acc -> Vec n x -> (acc,Vec n y)+vmapAccumL f acc xs = (acc',ys)+ where+ ws = vscanl (\l r -> f (fst l) r) (acc,undefined) xs+ acc' = fst (vlast ws)+ ys = vmap snd (vtail ws)++{-# INLINEABLE vmapAccumR #-}+vmapAccumR :: KnownNat n => (acc -> x -> (acc,y)) -> acc -> Vec n x -> (acc, Vec n y)+vmapAccumR f acc xs = (acc',ys)+ where+ ws = vscanr (\l r -> f (fst r) l) (acc,undefined) xs+ acc' = fst (vhead ws)+ ys = vmap snd (vinit ws)++{-# INLINEABLE vzip #-}+-- | 'vzip' takes two vectors and returns a vector of corresponding pairs. -- -- >>> vzip (1:>2:>3:>4:>Nil) (4:>3:>2:>1:>Nil) -- <(1,4),(2,3),(3,2),(4,1)> vzip :: Vec n a -> Vec n b -> Vec n (a,b)-vzip Nil Nil = Nil-vzip (x :> xs) (y :> ys) = (x,y) :> (vzip xs (unsafeCoerce ys))+vzip = vzipWith (,) -{-# NOINLINE vunzip #-}--- | 'vunzip' transforms a list of pairs into a list of first components--- and a list of second components.+{-# INLINEABLE vunzip #-}+-- | 'vunzip' transforms a vector of pairs into a vector of first components+-- and a vector of second components. -- -- >>> vunzip ((1,4):>(2,3):>(3,2):>(4,1):>Nil) -- (<1,2,3,4>,<4,3,2,1>) vunzip :: Vec n (a,b) -> (Vec n a, Vec n b)-vunzip Nil = (Nil,Nil)-vunzip ((a,b) :> xs) = let (as,bs) = vunzip xs- in (a :> as, b :> bs)+vunzip xs = (vmap fst xs, vmap snd xs) {-# NOINLINE vindexM_integer #-} vindexM_integer :: Vec n a -> Integer -> Maybe a@@ -388,7 +432,7 @@ Nothing -> error ("(!): Index " ++ show i ++ " is out of bounds 0 and " ++ show (maxIndex xs)) {-# INLINEABLE (!) #-}--- | Vector index (subscript) operator, descending from 'maxIndex', where the+-- | Vector index (subscript) operator, DESCENDING from 'maxIndex', where the -- last element has subscript 0. -- -- >>> (1:>2:>3:>4:>5:>Nil) ! 4@@ -535,7 +579,7 @@ vselect' UZero _ = Nil vselect' (USucc n') vs@(x :> _) = x :> vselect' n' (vdrop s (unsafeCoerce vs)) -{-# NOINLINE vselectI #-}+{-# INLINEABLE vselectI #-} -- | 'vselectI' @f s xs@ selects as many elements as demanded by the context -- with stepsize @s@ and offset @f@ from @xs@ --
src/CLaSH/Tutorial.hs view
@@ -831,12 +831,8 @@ * @~TYPM[N]@: VHDL type/name/ of the @(N+1)@'th argument; used in /type/ /qualification/. * @~TYPM@: VHDL type/name/ of the result; used in /type qualification/.-* @~DEF[N]@: Default value for the VHDL type of the @(N+1)@'th argument. NB:- Does not correspond per se to the value of 'def' of the 'Default' type class- for the Haskell type.-* @~DEFO@: Default value for the VHDL type of the result. NB: Does not- correspond per se to the value of the 'def' of the 'Default' type class for- the Haskell type.+* @~ERROR[N]@: Error value for the VHDL type of the @(N+1)@'th argument.+* @~ERRORO@: Error value for the VHDL type of the result. * @~SYM[N]@: Randomly generated, but unique, symbol. Multiple occurrences of @~SYM[N]@ in the same primitive definition all refer to the same random, but unique, symbol.