clash-prelude 0.9.2 → 0.9.3
raw patch · 9 files changed
+103/−82 lines, 9 filesdep ~singletonsPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: singletons
API changes (from Hackage documentation)
- CLaSH.Sized.Vector: dfold :: Proxy (p :: TyFun Nat * -> *) -> (forall l. Proxy l -> a -> p $ l -> p $ (l + 1)) -> (p $ 0) -> Vec k a -> p $ k
+ CLaSH.Sized.Vector: dfold :: Proxy (p :: TyFun Nat * -> *) -> (forall l. Proxy l -> a -> (p $ l) -> (p $ (l + 1))) -> (p $ 0) -> Vec k a -> (p $ k)
Files
- CHANGELOG.md +5/−0
- clash-prelude.cabal +2/−2
- src/CLaSH/Examples.hs +4/−4
- src/CLaSH/Prelude/BlockRam.hs +6/−6
- src/CLaSH/Prelude/Testbench.hs +12/−12
- src/CLaSH/Signal/Explicit.hs +2/−2
- src/CLaSH/Signal/Internal.hs +4/−5
- src/CLaSH/Sized/Vector.hs +2/−4
- src/CLaSH/Tutorial.hs +66/−47
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Changelog for [`clash-prelude` package](http://hackage.haskell.org/package/clash-prelude) +## 0.9.3 *September 21st 2015*+* Fixes bugs:+ * Cannot build against singletons-0.2+ * Numerous documentation fixes+ ## 0.9.2 *August 2nd 2015* * Disable strictness analysis in `CLaSH.Signal.Internal`, this allows turning on strictness analysis in the GHC front-end of the CLaSH compiler.
clash-prelude.cabal view
@@ -1,5 +1,5 @@ Name: clash-prelude-Version: 0.9.2+Version: 0.9.3 Synopsis: CAES Language for Synchronous Hardware - Prelude library Description: CλaSH (pronounced ‘clash’) is a functional hardware description language that@@ -141,7 +141,7 @@ ghc-typelits-natnormalise >= 0.3, lens >= 4.9, QuickCheck >= 2.7 && <2.9,- singletons >= 1.0,+ singletons >= 1.0 && <3.0, template-haskell >= 2.9.0.0, th-lift >= 0.5.6
src/CLaSH/Examples.hs view
@@ -212,7 +212,7 @@ -- when uld_rx_data $ do -- rx_data .= _rx_reg -- rx_empty .= True--- -- Recieve data only when rx is enabled+-- -- Receive data only when rx is enabled -- if rx_enable then do -- -- Check if just received start of frame -- when (not _rx_busy && _rx_d2 == 0) $ do@@ -452,7 +452,7 @@ | otherwise = x @ -Then we can instance a 16-bit LFSR as follows:+Then we can instantiate a 16-bit LFSR as follows: @ lfsrG :: BitVector 16 -> Signal Bit@@ -501,7 +501,7 @@ * Width = 16 bits * Truncated polynomial = 0x1021 * Initial value = 0xFFFF-* Input date is NOT reflected+* Input data is NOT reflected * Output CRC is NOT reflected * No XOR is performed on the output CRC @@ -556,7 +556,7 @@ 'when' uld_rx_data $ do rx_data '.=' _rx_reg rx_empty '.=' True- -- Recieve data only when rx is enabled+ -- Receive data only when rx is enabled if rx_enable then do -- Check if just received start of frame 'when' (not _rx_busy && _rx_d2 == 0) $ do
src/CLaSH/Prelude/BlockRam.hs view
@@ -187,8 +187,8 @@ And test our system: @-__>>> L.take 31 $ sample $ system prog__-[0,0,0,0,0,4,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+__>>> sampleN 31 $ system prog__+[0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2] @ to see that our system indeed calculates that the GCD of 6 and 4 is 2.@@ -217,8 +217,8 @@ output samples are also 'undefined'. @-__>>> L.take 26 $ L.drop 5 $ sample $ system2 prog__-[4,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+__>>> L.drop 5 $ sampleN 31 $ system2 prog__+[4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2] @ === Improvement 2: using @blockRam@@@ -336,8 +336,8 @@ also 'undefined'. @-__>>> L.take 32 $ L.tail $ sample $ system3 prog2__-[4,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2]+__>>> L.tail $ sampleN 33 $ system3 prog2__+[0,0,0,0,0,4,4,4,4,4,4,4,4,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,2] @ This concludes the short introduction to using 'blockRam'.
src/CLaSH/Prelude/Testbench.hs view
@@ -50,18 +50,18 @@ -- function is used by 'outputVerifier'. -- ----- __NB__: This function is /can/ be used in synthesizable designs.+-- __NB__: This function /can/ be used in synthesizable designs. assert :: (Eq a,Show a) => String -- ^ Additional message -> Signal a -- ^ Checked value -> Signal a -- ^ Expected value- -> Signal b -- ^ Return valued+ -> Signal b -- ^ Return value -> Signal b assert = assert' systemClock {-# INLINE stimuliGenerator #-}--- | To be used as a one of the functions to create the \"magical\" 'testInput'--- value, which the CλaSH compilers looks for to create the stimulus generator+-- | To be used as one of the functions to create the \"magical\" 'testInput'+-- value, which the CλaSH compiler looks for to create the stimulus generator -- for the generated VHDL testbench. -- -- Example:@@ -79,8 +79,8 @@ stimuliGenerator = stimuliGenerator' systemClock {-# INLINE outputVerifier #-}--- | To be used as a functions to generate the \"magical\" 'expectedOutput'--- function, which the CλaSH compilers looks for to create the signal verifier+-- | To be used as one of the functions to generate the \"magical\" 'expectedOutput'+-- function, which the CλaSH compiler looks for to create the signal verifier -- for the generated VHDL testbench. -- -- Example:@@ -124,13 +124,13 @@ -- function is used by 'outputVerifier''. -- ----- __NB__: This function is /can/ be used in synthesizable designs.+-- __NB__: This function /can/ be used in synthesizable designs. assert' :: (Eq a,Show a) => SClock t -> String -- ^ Additional message -> Signal' t a -- ^ Checked value -> Signal' t a -- ^ Expected value- -> Signal' t b -- ^ Return valued+ -> Signal' t b -- ^ Return value -> Signal' t b assert' clk msg checked expected returned = (\c e cnt r ->@@ -147,8 +147,8 @@ <$> checked <*> expected <*> fromList [(0::Integer)..] <*> returned {-# INLINABLE stimuliGenerator' #-}--- | To be used as a one of the functions to create the \"magical\" 'testInput'--- value, which the CλaSH compilers looks for to create the stimulus generator+-- | To be used as one of the functions to create the \"magical\" 'testInput'+-- value, which the CλaSH compiler looks for to create the stimulus generator -- for the generated VHDL testbench. -- -- Example:@@ -184,8 +184,8 @@ else s {-# INLINABLE outputVerifier' #-}--- | To be used as a functions to generate the \"magical\" 'expectedOutput'--- function, which the CλaSH compilers looks for to create the signal verifier+-- | To be used as one of the functions to generate the \"magical\" 'expectedOutput'+-- function, which the CλaSH compiler looks for to create the signal verifier -- for the generated VHDL testbench. -- -- Example:
src/CLaSH/Signal/Explicit.hs view
@@ -103,7 +103,7 @@ * __NB__: \"Bad things\"™ happen when you actually use a clock period of @0@, so do __not__ do that! * __NB__: You should be judicious using a clock with period of @1@ as you can-never create a clock that faster!+never create a clock that goes any faster! -} -- * Clock domain crossing@@ -158,7 +158,7 @@ -- type DAC36 = 'Clk' \"DAC\" 25 -- type Sys50 = 'Clk' \"Sys\" 18 ----- sys50 :: SClock System50+-- sys50 :: SClock Sys50 -- sys50 = 'sclock' -- -- adc20 :: SClock ADC20
src/CLaSH/Signal/Internal.hs view
@@ -260,8 +260,7 @@ -- -- Create a constant 'CLaSH.Signal.Signal' from a combinational value ----- >>> import qualified Data.List as List--- >>> List.take 5 (sample (signal 4 :: Signal Int))+-- >>> sampleN 5 (signal 4 :: Signal Int) -- [4,4,4,4,4] signal :: Applicative f => a -> f a signal = pure@@ -324,7 +323,7 @@ -- | The above type is a generalisation for: -- -- @--- __compare__ :: 'Ord' a => 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' 'Ordering'+-- __compare1__ :: 'Ord' a => 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' 'Ordering' -- @ -- -- It is a version of 'compare' that returns a 'CLaSH.Signal.Signal' of 'Ordering'@@ -403,10 +402,10 @@ -- | The above type is a generalisation for: -- -- @--- __fromEnum1__ :: 'Real' a => 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' 'Rational'+-- __toRational1__ :: 'Real' a => 'CLaSH.Signal.Signal' a -> 'CLaSH.Signal.Signal' 'Rational' -- @ ----- | It is a version of 'toRational' that returns a 'CLaSH.Signal.Signal' of 'Rational'+-- It is a version of 'toRational' that returns a 'CLaSH.Signal.Signal' of 'Rational' toRational1 :: (Real a, Functor f) => f a -> f Rational toRational1 = fmap toRational
src/CLaSH/Sized/Vector.hs view
@@ -163,7 +163,6 @@ where f EQ keepGoing = keepGoing f done _ = done --- | __NB__: Not synthesisable instance KnownNat n => Applicative (Vec n) where pure = repeat fs <*> xs = zipWith ($) fs xs@@ -174,7 +173,6 @@ instance Functor (Vec n) where fmap = map --- | __NB__: Not synthesisable instance Traversable (Vec n) where traverse = traverse# @@ -1186,10 +1184,10 @@ -- >>> append' (1 :> 2 :> Nil) (3 :> 4 :> Nil) -- <1,2,3,4> dfold :: Proxy (p :: TyFun Nat * -> *) -- ^ The /motive/- -> (forall l . Proxy l -> a -> p $ l -> p $ (l + 1)) -- ^ Function to fold+ -> (forall l . Proxy l -> a -> (p $ l) -> (p $ (l + 1))) -- ^ Function to fold -> (p $ 0) -- ^ Initial element -> Vec k a -- ^ Vector to fold over- -> p $ k+ -> (p $ k) dfold _ _ z Nil = z dfold p f z (x :> (xs :: Vec l a)) = f (Proxy :: Proxy l) x (dfold p f z xs)
src/CLaSH/Tutorial.hs view
@@ -71,8 +71,11 @@ import CLaSH.Prelude import CLaSH.Prelude.Explicit import CLaSH.Prelude.BlockRam+import Control.Monad.ST+import Data.Array import Data.Char import Data.Int+import GHC.Prim import GHC.Word import Data.Default @@ -173,8 +176,8 @@ * Run: @sudo add-apt-repository -y ppa:hvr/ghc@ * Run: @sudo apt-get update@- * Run: @sudo apt-get install cabal-install-1.22 ghc-7.10.1 libtinfo-dev@- * Update your @PATH@ with: @\/opt\/ghc\/7.10.1\/bin@, @\/opt\/cabal\/1.22/bin@, and @\$HOME\/.cabal\/bin@+ * Run: @sudo apt-get install cabal-install-1.22 ghc-7.10.2 libtinfo-dev@+ * Update your @PATH@ with: @\/opt\/ghc\/7.10.2\/bin@, @\/opt\/cabal\/1.22/bin@, and @\$HOME\/.cabal\/bin@ * Run: @cabal update@ * Skip step 2. @@ -750,8 +753,8 @@ @ instance 'Bundle' Bool where type 'Unbundled'' clk Bool = 'Signal'' clk Bool- bundle' _ s = s- unpack' _ s = s+ bundle' _ s = s+ unbundle' _ s = s @ What you need take away from the above is that a product type (e.g. a tuple) of@@ -1117,7 +1120,7 @@ * @~TYPELEM[\<HOLE\>]@: The element type of the vector type represented by @\<HOLE\>@. The content of @\<HOLE\>@ must either be: @TYPM[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@. * @~COMPNAME@: The name of the component in which the primitive is instantiated.-* @~LENGHT[\<HOLE\>]@: The vector length of the type represented by @\<HOLE\>@.+* @~LENGTH[\<HOLE\>]@: The vector length of the type represented by @\<HOLE\>@. The content of @\<HOLE\>@ must either be: @TYPM[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@. * @~SIZE[\<HOLE\>]@: The number of bits needed to encode the type represented by @\<HOLE\>@. The content of @\<HOLE\>@ must either be: @TYPM[N]@, @TYPO@, or @TYPELEM[\<HOLE\>]@.@@ -1253,7 +1256,7 @@ the code to build the FIFO synchroniser based on the design described in: <http://www.sunburst-design.com/papers/CummingsSNUG2002SJ_FIFO1.pdf> -We start with enable a few options that will make wring the type-signatures for+We start with enable a few options that will make writing the type-signatures for our components a bit easier. We'll also import the standard "CLaSH.Prelude" module, and the "CLaSH.Prelude.Explicit" module for our explicitly clocked synchronous functions:@@ -1267,24 +1270,22 @@ import CLaSH.Prelude.Explicit @ -Then we'll start with the /hart/ of the FIFO synchroniser, an asynchronous RAM+Then we'll start with the /heart/ of the FIFO synchroniser, an asynchronous RAM in the form of 'asyncRam''. It's called an asynchronous RAM because the read port is not synchronised to any clock (though the write port is). Note that in CλaSH we don't really have asynchronous logic, there is only combinational and synchronous logic. As a consequence, we see in the type signature of 'asyncRam'': - *-- @- __asyncRam'__ :: _ => SClock wclk -- ^ Clock to which to synchronise the write port of the RAM- -> SClock rclk -- ^ Clock to which the read address signal __r__ is synchronised- -> SNat n -- ^ Size __n__ of the RAM- -> Signal' wclk addr -- ^ Write address __w__- -> Signal' rclk addr -- ^ Read address __r__- -> Signal' wclk Bool -- ^ Write enable- -> Signal' wclk a -- ^ Value to write (at address __w__)- -> Signal' rclk a -- ^ Value of the RAM at address __r__- @+@+__asyncRam'__ :: _ => SClock wclk -- ^ Clock to which to synchronise the write port of the RAM+ -> SClock rclk -- ^ Clock to which the read address signal __r__ is synchronised+ -> SNat n -- ^ Size __n__ of the RAM+ -> Signal' wclk addr -- ^ Write address __w__+ -> Signal' rclk addr -- ^ Read address __r__+ -> Signal' wclk Bool -- ^ Write enable+ -> Signal' wclk a -- ^ Value to write (at address __w__)+ -> Signal' rclk a -- ^ Value of the RAM at address __r__+@ that the signal containing the read address __r__ is synchronised to a different clock. That is, there is __no__ such thing as an @AsyncSignal@ in CλaSH.@@ -1376,8 +1377,8 @@ -> (Signal' rclk a, Signal' rclk Bool, Signal' wclk Bool) fifo addrSize wclk rclk wdata winc rinc = (rdata,rempty,wfull) where- s_rptr = ptrSync wclk rclk rptr- s_wptr = ptrSync rclk wclk wptr+ s_rptr = ptrSync rclk wclk rptr+ s_wptr = ptrSync wclk rclk wptr rdata = fifoMem wclk rclk addrSize waddr raddr winc wfull wdata @@ -1515,7 +1516,7 @@ Signals of product types and product types (to which tuples belong) of signals are __isomorphic__ due to synchronisity principle, but are not- (structurally) equal. Use the 'pack' function to convert from a product type+ (structurally) equal. Use the 'bundle' function to convert from a product type to the signal type. So if your code which gives the error looks like: @@@ -1528,19 +1529,19 @@ ... = f a b ('bundle' (c,d)) @ - Product types supported by 'bundle are:+ Product types supported by 'bundle' are: * All tuples until and including 8-tuples * The 'Vec'tor type - NB: Use 'bundle'' when you are using explicitly clocked 'CLaSH.Signal.Explicit.Signal''s+ NB: Use 'bundle'' when you are using explicitly clocked @'Signal''@s * __Type error: Couldn't match expected type @('Signal' a, 'Signal' b)@ with__ __ actual type @'Signal' (a,b)@__: Product types (to which tuples belong) of signals and signals of product types are __isomorphic__ due to synchronicity principle, but are not- (structurally) equal. Use the 'unpack' function to convert from a signal+ (structurally) equal. Use the 'unbundle' function to convert from a signal type to the product type. So if your code which gives the error looks like: @@@ -1553,12 +1554,12 @@ (c,d) = 'unbundle' (f a b) @ - Product types supported by 'unbundle are:+ Product types supported by 'unbundle' are: * All tuples until and including 8-tuples * The 'Vec'tor type - NB: Use 'unbundle'' when you are using explicitly clocked 'CLaSH.Signal.Explicit.Signal''s+ NB: Use 'unbundle'' when you are using explicitly clocked @'Signal''@s * __CLaSH.Netlist(..): Not in normal form: \<REASON\>: \<EXPR\>__: @@ -1667,7 +1668,7 @@ Here is a list of Haskell features which the CλaSH compiler cannot synthesize to VHDL/Verilog/SystemVerilog (for now): - [@Recursive functions@]+* __Recursive functions__ Although it seems rather bad that a compiler for a functional language does not support recursion, this bug/feature of the@@ -1692,7 +1693,7 @@ Where we can clearly see that 'lefts' and 'sorted' are defined in terms of each other. - [@Recursive datatypes@]+* __Recursive datatypes__ The CλaSH compiler needs to be able to determine a bit-size for any value that will be represented in the eventual circuit. More specifically, we need@@ -1706,7 +1707,7 @@ For \"easy\" 'Vec'tor literals you should use Template Haskell splices and the 'v' /meta/-function that as we have seen earlier in this tutorial. - [@GADT pattern matching@]+* __GADT pattern matching__ While pattern matching for regular ADTs is supported, pattern matching for GADTs is __not__. The 'Vec'tor type, which is also a GADT, is __no__@@ -1714,30 +1715,48 @@ "CLaSH.Sized.Vector" to get access to individual ranges / elements of a 'Vec'tor. - [@Floating point types@]+* __Floating point types__ There is no support for the 'Float' and 'Double' types, if you need numbers with a /fractional/ part you can use the 'Fixed' point type. - [@Other primitive types@]+ As to why there is no support for these floating point types: - Most primitive types are not supported, with the exception of 'Int',- @<http://hackage.haskell.org/package/ghc-prim/docs/GHC-Prim.html#t:Int-35- Int#>@,- and 'Integer'. This means that types such as: 'Word', 'Word8', 'Int8', 'Char',- @<http://hackage.haskell.org/package/array/docs/Data-Array.html#t:Array Array>@,- etc. cannot to translated to hardware.+ 1. In order to achieve reasonable operating frequencies, arithmetic+ circuits for floating point data types must be pipelined. - The translations of 'Int',- @<http://hackage.haskell.org/package/ghc-prim/docs/GHC-Prim.html#t:Int-35- Int#>@,- and 'Integer' are also incorrect: they are translated to the VHDL @integer@- type, the Verilog @signed [31:0], or the SystemVerilog @signed logic [31:0]@- type, which can only represent 32-bit integer values. Use these types with- due diligence.+ 2. Haskell's primitive arithmetic operators on floating point data types,+ such as 'plusFloat#' - [@Side-effects: 'IO', 'Control.Monad.ST.ST', etc.@]+ @+ __plusFloat#__ :: 'Float#' -> 'Float#' -> 'Float#'+ @ + which underlie @'Float'@'s 'Num' instance, must be implemented as+ purely combinational circuits according to their type. Remember,+ sequential circuits operate on values of type \"@'Signal' a@\".++ Although it is possible to implement purely combinational (not pipelined)+ arithmetic circuits for floating point data types, the circuit would be+ unreasonable slow. And so, without synthesis possibilities for the basic+ arithmetic operations, there is no point in supporting the floating point+ data types.++* __Other primitive types__++ Most primitive types are not supported, with the exception of 'Int', 'Int#',+ and 'Integer'. This means that types such as: 'Word', 'Word8', 'Int8',+ 'Char', 'Array', etc. cannot to translated to hardware.++ The translations of 'Int', 'Int#', and 'Integer' are also incorrect: they+ are translated to the VHDL @integer@ type, the Verilog @signed [31:0], or+ the SystemVerilog @signed logic [31:0]@ type, which can only represent+ 32-bit integer values. Use these types with due diligence.++* __Side-effects: 'IO', 'ST', etc.__+ There is no support for side-effecting computations such as those in the- 'IO' or 'Control.Monad.ST.ST' monad. There is also no support for Haskell's+ 'IO' or 'ST' monad. There is also no support for Haskell's <http://www.haskell.org/haskellwiki/Foreign_Function_Interface FFI>. -} @@ -1768,8 +1787,8 @@ * Synthesis of all choice constructs (pattern matching, guards, etc.) * 'Applicative' instance for the 'Signal' type * Working with \"normal\" functions permits the use of e.g. the- <http://hackage.haskell.org/package/mtl/docs/Control-Monad-State-Lazy.html#t:State State>- monad to describe the functionality of a circuit.+ 'Control.Monad.State.Lazy.State' monad to describe the functionality of a+ circuit. Although there are Lava alternatives to some of the above features (e.g. first-class patterns to replace pattern matching) they are not as \"beautiful\"