diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -1,2 +1,2 @@
 = WARNING =
-Only works with GHC-7.8 (http://www.haskell.org/ghc/dist/7.8.1-rc2/)!
+Only works with GHC-7.8.* (http://www.haskell.org/ghc/download_ghc_7_8_2)!
diff --git a/clash-prelude.cabal b/clash-prelude.cabal
--- a/clash-prelude.cabal
+++ b/clash-prelude.cabal
@@ -1,5 +1,5 @@
 Name:                 clash-prelude
-Version:              0.5
+Version:              0.5.0.1
 Synopsis:             CAES Language for Synchronous Hardware - Prelude library
 Description:
   CλaSH (pronounced ‘clash’) is a functional hardware description language that
@@ -16,6 +16,7 @@
   To use the library:
   .
   * Import "CLaSH.Prelude"
+  .
   * Additionally import "CLaSH.Prelude.Explicit" if you want to design
     explicitly clocked circuits in a multi-clock setting
   .
diff --git a/src/CLaSH/Bit.hs b/src/CLaSH/Bit.hs
--- a/src/CLaSH/Bit.hs
+++ b/src/CLaSH/Bit.hs
@@ -11,8 +11,8 @@
 import Language.Haskell.TH.Lift
 
 -- | Two-level logic
-data Bit = H -- ^ High
-         | L -- ^ Low
+data Bit = L -- ^ Low
+         | H -- ^ High
 
 instance Eq Bit where
   (==) = eqBit
diff --git a/src/CLaSH/Prelude.hs b/src/CLaSH/Prelude.hs
--- a/src/CLaSH/Prelude.hs
+++ b/src/CLaSH/Prelude.hs
@@ -180,10 +180,12 @@
 registerP i = unpack Prelude.. register i Prelude.. pack
 
 {-# NOINLINE blockRam #-}
--- | Create a blockRAM with space for @n@ elements
+-- | Create a blockRAM with space for @n@ elements.
 --
+-- NB: Read value is delayed by 1 cycle
+--
 -- > bram40 :: Signal (Unsigned 6) -> Signal (Unsigned 6) -> Signal Bool -> Signal a -> Signal a
--- > bram40 = blockRam d50
+-- > bram40 = blockRam d40
 blockRam :: forall n m a . (KnownNat n, KnownNat m, Pack a, Default a)
          => SNat n              -- ^ Size @n@ of the blockram
          -> Signal (Unsigned m) -- ^ Write address @w@
@@ -204,11 +206,13 @@
              | otherwise = ram
         o'               = ram ! r
 
-{-# DEPRECATED blockRamC "'Comp' is deprecated, use 'blockRam' instead" #-}
+{-# 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
+--
 -- > bramC40 :: Comp (Unsigned 6, Unsigned 6, Bool, a) a
--- > bramC40 = blockRamC d50
+-- > bramC40 = blockRamC d40
 blockRamC :: (KnownNat n, KnownNat m, Pack a, Default a)
           => SNat n -- ^ Size @n@ of the blockram
           -> Comp (Unsigned m, Unsigned m, Bool, a) a
@@ -217,6 +221,8 @@
 {-# INLINABLE blockRamPow2 #-}
 -- | Create a blockRAM with space for 2^@n@ elements
 --
+-- NB: Read value is delayed by 1 cycle
+--
 -- > 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)
@@ -228,9 +234,11 @@
              -> Signal a            -- ^ Value of the 'blockRAM' at address @r@ from the previous clock cycle
 blockRamPow2 = blockRam
 
-{-# DEPRECATED blockRamPow2C "'Comp' is deprecated, use 'blockRamPow2' instead" #-}
+{-# 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
+--
 -- > bramC32 :: Comp (Unsigned 5, Unsigned 5, Bool, a) a
 -- > bramC32 = blockRamPow2C d32
 blockRamPow2C :: (KnownNat n, KnownNat (2^n), Pack a, Default a)
@@ -238,7 +246,7 @@
               -> Comp (Unsigned n, Unsigned n, Bool, a) a
 blockRamPow2C n = C ((\(wr,rd,en,din) -> blockRamPow2 n wr rd en din) Prelude.. unpack)
 
-{-# DEPRECATED Comp "Use 'Applicative' interface and ('<^>') instead" #-}
+{-# DEPRECATED Comp "Will be removed in version 0.6. Use 'Applicative' interface and ('<^>') instead" #-}
 -- | 'Comp'onent: an 'Arrow' interface to synchronous sequential functions
 newtype Comp  a b = C { asFunction :: Signal a -> Signal b }
 
@@ -258,7 +266,7 @@
       simpleLoop g b = let ~(c,d) = g (b,d)
                        in c
 
-{-# DEPRECATED registerC "'Comp' is deprecated, use 'register' instead" #-}
+{-# DEPRECATED registerC "'Comp' is deprecated and will be removed in version 0.6, use 'register' instead" #-}
 -- | Create a 'register' 'Comp'onent
 --
 -- > rC :: Comp (Int,Int) (Int,Int)
@@ -269,7 +277,7 @@
 registerC :: a -> Comp a a
 registerC = C Prelude.. register
 
-{-# DEPRECATED simulateC "'Comp' is deprecated, use 'simulate' instead" #-}
+{-# DEPRECATED simulateC "'Comp' is deprecated and will be removed in version 0.6, use 'simulate' instead" #-}
 -- | Simulate a 'Comp'onent given a list of samples
 --
 -- >>> simulateC (registerC 8) [1, 2, 3, ...
@@ -277,7 +285,7 @@
 simulateC :: Comp a b -> [a] -> [b]
 simulateC f = simulate (asFunction f)
 
-{-# DEPRECATED (^^^) "Use 'Applicative' interface and ('<^>') instead" #-}
+{-# DEPRECATED (^^^) "Will be removed in version 0.6. Use 'Applicative' interface and ('<^>') instead" #-}
 {-# INLINABLE (^^^) #-}
 -- | Create a synchronous 'Comp'onent from a combinational function describing
 -- a mealy machine
diff --git a/src/CLaSH/Prelude/Explicit.hs b/src/CLaSH/Prelude/Explicit.hs
--- a/src/CLaSH/Prelude/Explicit.hs
+++ b/src/CLaSH/Prelude/Explicit.hs
@@ -104,7 +104,7 @@
 cregisterP :: CPack a => Clock clk -> a -> CSignalP clk a -> CSignalP clk a
 cregisterP clk i = cunpack clk Prelude.. cregister clk i Prelude.. cpack clk
 
-{-# DEPRECATED CComp "Use 'Applicative' interface and 'sync' instead" #-}
+{-# DEPRECATED CComp "Will be removed in version 0.6. Use 'Applicative' interface and 'sync' instead" #-}
 -- | 'CComp'onent: an 'Arrow' interface to explicitly clocked synchronous
 -- sequential functions
 newtype CComp t a b = CC { asCFunction :: CSignal t a -> CSignal t b }
@@ -127,7 +127,7 @@
       simpleLoop g b = let ~(c,d) = g (b,d)
                        in c
 
-{-# DEPRECATED syncA "Use 'Applicative' interface and 'sync' instead" #-}
+{-# DEPRECATED syncA "Will be removed in version 0.6. Use 'Applicative' interface and 'sync' instead" #-}
 {-# INLINABLE syncA #-}
 -- | Create a synchronous 'CComp'onent from a combinational function describing
 -- a mealy machine
@@ -162,7 +162,7 @@
                                 s      = cregister clk sI s'
                             in  o
 
-{-# DEPRECATED cregisterC "'CComp' is deprecated, use 'cregister' instead" #-}
+{-# DEPRECATED cregisterC "'CComp' is deprecated and will be removed in version 0.6, use 'cregister' instead" #-}
 -- | Create a 'cregister' 'CComp'onent
 --
 -- > clk100 = Clock d100
@@ -175,7 +175,7 @@
 cregisterC :: Clock clk -> a -> CComp clk a a
 cregisterC clk = CC Prelude.. cregister clk
 
-{-# DEPRECATED csimulateC "'CComp' is deprecated, use 'csimulate' instead" #-}
+{-# DEPRECATED csimulateC "'CComp' is deprecated and will be removed in version 0.6, use 'csimulate' instead" #-}
 -- | Simulate a 'Comp'onent given a list of samples
 --
 -- > clk100 = Clock d100
@@ -187,11 +187,13 @@
 {-# NOINLINE cblockRam #-}
 -- | Create a blockRAM with space for @n@ elements
 --
+-- NB: Read value is delayed by 1 cycle
+--
 -- > clk100 = Clock d100
 -- >
 -- > bram40 :: CSignal 100 (Unsigned 6) -> CSignal 100 (Unsigned 6)
 -- >        -> CSignal 100 Bool -> CSignal 100 a -> 100 CSignal a
--- > bram40 = cblockRam clk100 d50
+-- > bram40 = cblockRam clk100 d40
 cblockRam :: forall n m a clk . (KnownNat n, KnownNat m, CPack a, Default a)
           => Clock clk                -- ^ 'Clock' to synchronize to
           -> SNat n                   -- ^ Size @n@ of the blockram
@@ -213,13 +215,15 @@
              | otherwise = ram
         o'               = ram ! r
 
-{-# DEPRECATED blockRamCC "'CComp' is deprecated, use 'cblockRam' instead" #-}
+{-# 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
+--
 -- > clk100 = Clock 100
 -- >
 -- > bramC40 :: CComp 100 (Unsigned 6, Unsigned 6, Bool, a) a
--- > bramC40 = blockRamCC clk100 d50
+-- > bramC40 = blockRamCC clk100 d40
 blockRamCC :: (KnownNat n, KnownNat m, CPack a, Default a)
            => Clock clk -- ^ 'Clock' to synchronize to
            -> SNat n    -- ^ Size @n@ of the blockram
@@ -229,6 +233,8 @@
 {-# INLINABLE cblockRamPow2 #-}
 -- | Create a blockRAM with space for 2^@n@ elements
 --
+-- NB: Read value is delayed by 1 cycle
+--
 -- > 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)
@@ -241,8 +247,10 @@
               -> CSignal clk a            -- ^ Value of the 'blockRAM' at address @r@ from the previous clock cycle
 cblockRamPow2 = cblockRam
 
-{-# DEPRECATED blockRamPow2CC "'CComp' is deprecated, use 'cblockRamPow2' instead" #-}
+{-# 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
 --
 -- > clk100 = Clock d100
 -- >
diff --git a/src/CLaSH/Signal/Explicit.hs b/src/CLaSH/Signal/Explicit.hs
--- a/src/CLaSH/Signal/Explicit.hs
+++ b/src/CLaSH/Signal/Explicit.hs
@@ -115,6 +115,13 @@
 
 -- | Isomorphism between a @'CSignal' clk@ of a product type (e.g. a tuple) and a
 -- product type of @'CSignal' clk@'s
+--
+-- Instances of 'CPack' must satisfy the following laws:
+--
+-- @
+-- cpack clk . cunpack clk = 'id'
+-- cunpack clk . cpack clk = 'id'
+-- @
 class CPack a where
   type CSignalP (clk :: Nat) a
   type CSignalP clk a = CSignal clk a
diff --git a/src/CLaSH/Signal/Implicit.hs b/src/CLaSH/Signal/Implicit.hs
--- a/src/CLaSH/Signal/Implicit.hs
+++ b/src/CLaSH/Signal/Implicit.hs
@@ -79,7 +79,14 @@
 simulate f = sample . f . fromList
 
 -- | Isomorphism between a 'Signal' of a product type (e.g. a tuple) and a
--- product type of 'Signal's
+-- product type of 'Signal's.
+--
+-- Instances of 'Pack' must satisfy the following laws:
+--
+-- @
+-- pack . unpack = 'id'
+-- unpack . pack = 'id'
+-- @
 class Pack a where
   type SignalP a
   -- | Example:
diff --git a/src/CLaSH/Sized/Vector.hs b/src/CLaSH/Sized/Vector.hs
--- a/src/CLaSH/Sized/Vector.hs
+++ b/src/CLaSH/Sized/Vector.hs
@@ -385,7 +385,7 @@
 vindex_integer :: KnownNat n => Vec n a -> Integer -> a
 vindex_integer xs i = case vindexM_integer xs (maxIndex xs - i) of
     Just a  -> a
-    Nothing -> error "index out of bounds"
+    Nothing -> error ("(!): Index " ++ show i ++ " is out of bounds 0 and " ++ show (maxIndex xs))
 
 {-# INLINEABLE (!) #-}
 -- | Vector index (subscript) operator, descending from 'maxIndex', where the
@@ -430,7 +430,7 @@
 vreplace_integer :: KnownNat n => Vec n a -> Integer -> a -> Vec n a
 vreplace_integer xs i a = case vreplaceM_integer xs (maxIndex xs - i) a of
   Just ys -> ys
-  Nothing -> error "index out of bounds"
+  Nothing -> error ("vreplace: Index " ++ show i ++ " is out of bounds 0 and " ++ show (maxIndex xs))
 
 {-# INLINEABLE vreplace #-}
 -- | Replace an element of a vector at the given index (subscript).
@@ -649,12 +649,12 @@
 -- > compareSwapL a b = if a < b then (a,b)
 -- >                             else (b,a)
 --
--- Will not terminate because 'vzipWith' is too strict in its left argument:
+-- Will not terminate because 'vzipWith' is too strict in its second argument:
 --
 -- >>> sortV (4 :> 1 :> 2 :> 3 :> Nil)
 -- <*** Exception: <<loop>>
 --
--- In this case, adding 'lazyV' on 'vzipWith's left argument:
+-- In this case, adding 'lazyV' on 'vzipWith's second argument:
 --
 -- > sortVL xs = vmap fst sorted <: (snd (vlast sorted))
 -- >  where
diff --git a/src/CLaSH/Tutorial.hs b/src/CLaSH/Tutorial.hs
--- a/src/CLaSH/Tutorial.hs
+++ b/src/CLaSH/Tutorial.hs
@@ -35,6 +35,9 @@
   -- * Composition of sequential circuits
   -- $composition_sequential
 
+  -- * Advanced: VHDL primitives
+  -- $vhdlprimitives
+
   -- * Conclusion
   -- $conclusion
 
@@ -43,19 +46,27 @@
 
   -- * Unsupported Haskell features
   -- $unsupported
+
+  -- * CλaSH vs Lava
+  -- $vslava
   )
 where
 
 import CLaSH.Prelude
 import CLaSH.Prelude.Explicit
+import Data.Char
+import Data.Int
+import GHC.Word
 
+
 {- $introduction
 CλaSH (pronounced ‘clash’) is a functional hardware description language that
 borrows both its syntax and semantics from the functional programming language
 Haskell. The merits of using a functional language to describe hardware comes
 from the fact that combinational circuits can be directly modeled as
 mathematical functions and that functional languages lend themselves very well
-at describing and (de-)composing mathematical functions.
+at describing and (de-)composing mathematical functions. The CλaSH compiler
+transforms these high-level descriptions to low-level synthesizable VHDL.
 
 Although we say that CλaSH borrows the semantics of Haskell, that statement
 should be taken with a grain of salt. What we mean to say is that the CλaSH
@@ -65,13 +76,13 @@
 consequences on how we view /recursive/ functions: structurally, a recursive
 function would denote an /infinitely/ deep / structured component, something
 that cannot be turned into an actual circuit (See also <#unsupported Unsupported Haskell features>).
-Of course there are variants of recursion that cab be completely unfolded at
+Of course there are variants of recursion that could be completely unfolded at
 compile-time with a finite amount of steps and hence could be converted to a
 realisable circuit. Sadly, this last feature is missing in the current version
 of the compiler.
 
-On the other hand, Haskell's by-default non-strict evaluation corresponds very
-well to the simulation of the feedback loops which are ubiquitous in digital
+On the other hand, Haskell's by-default non-strict evaluation works very well
+for the simulation of the feedback loops, which are ubiquitous in digital
 circuits. That is, when we take our structural view to circuit descriptions,
 value-recursion corresponds directly to a feedback loop:
 
@@ -81,10 +92,10 @@
     s = register 0 (s + 1)
 @
 
-Over time, you will get a better feeling of what exact the consequences are of
-taking a \structural\ view on circuit descriptions. What is always important to
+Over time, you will get a better feeling for the consequences of taking a
+/structural/ view on circuit descriptions. What is always important to
 remember is that every applied functions results in an instantiated component,
-and also that the compiler will never infer / invent more logic than what is
+and also that the compiler will /never/ infer / invent more logic than what is
 specified in the circuit description.
 
 With that out of the way, let us continue with installing CλaSH and building
@@ -93,9 +104,9 @@
 
 {- $installation
 The CλaSH compiler and Prelude library for circuit design only work with the
-<http://haskell.org/ghc GHC> Haskell compiler version 7.8.1 and up.
+<http://haskell.org/ghc GHC> Haskell compiler version 7.8.* and up.
 
-  (1) Install __GHC (version 7.8.1 or higher)__
+  (1) Install __GHC (version 7.8.* or higher)__
 
       * Download and install <http://www.haskell.org/ghc/download GHC for your platform>.
         Unix user can use @./configure prefix=\<LOCATION\>@ to set the installation
@@ -105,12 +116,12 @@
 
   (2) Install __Cabal__
 
-      * Windows:
+      * Windows and OS X Mavericks:
 
           * Download the binary for <http://www.haskell.org/cabal/download.html cabal-install>
           * Put the binary in a location mentioned in your @PATH@
 
-      * Unix:
+      * Other Unix systems:
 
           * Download the sources for <http://hackage.haskell.org/package/cabal-install cabal-install>
           * Unpack (@tar xf@) the archive and @cd@ to the directory
@@ -129,7 +140,7 @@
       * Run @clash --interactive FIR.hs@
       * Execute, in the interpreter, the @:vhdl@ command.
       * Exit the interpreter using @:q@
-      * Examin the VHDL code in the @vhdl@ directory
+      * Examine the VHDL code in the @vhdl@ directory
 
 -}
 
@@ -173,28 +184,28 @@
 and accumulates them. Before we describe any logic, we must first create the
 file we will be working on and input some preliminaries:
 
-  * Create the file:
+* Create the file:
 
-      @
-      MAC.hs
-      @
+    @
+    MAC.hs
+    @
 
-  * Write on the first line the module header:
+* Write on the first line the module header:
 
-      @
-      module MAC where
-      @
+    @
+    module MAC where
+    @
 
-      Module names must always start with a __C__apital letter. Also make sure that
-      the file name corresponds to the module name.
+    Module names must always start with a __C__apital letter. Also make sure that
+    the file name corresponds to the module name.
 
-  * Add the import statement for the CλaSH prelude library:
+* Add the import statement for the CλaSH prelude library:
 
-      @
-      import CLaSH.Prelude
-      @
+    @
+    import CLaSH.Prelude
+    @
 
-      This imports all the necessary functions and datatypes for circuit description.
+    This imports all the necessary functions and datatypes for circuit description.
 
 We can now finally start describing the logic of our circuit, starting with just
 the multiplication and addition:
@@ -214,7 +225,7 @@
 We can also examine the inferred type of @ma@ in the interpreter:
 
 >>> :t ma
-ma :: Num a => a -> a -> a
+ma :: Num a => a -> (a, a) -> a
 
 Talking about /types/ also brings us to one of the most important parts of this
 tutorial: /types/ and /synchronous sequential logic/. Especially how we can
@@ -336,7 +347,7 @@
 type instance SignalP (a,b) = (Signal a, Signal b)
 @
 
-'SignalP' is an <http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl associcated type family>
+'SignalP' is an <http://www.haskell.org/ghc/docs/latest/html/users_guide/type-families.html#assoc-decl associated type family>
 belonging to the 'Pack' <http://en.wikipedia.org/wiki/Type_class type class>,
 which, together with 'pack' and 'unpack' defines the isomorphism between a
 product type of 'Signal's and a 'Signal' of a product type. That is, while
@@ -442,7 +453,7 @@
 topEntity :: SignalP a -> SignalP b
 @
 
-Where @a@ and @b@ are placeholders for monomorphics types: the 'topEntity' is
+Where @a@ and @b@ are placeholders for monomorphic types: the 'topEntity' is
 not allowed to be polymorphic. So given the above type for the 'topEntity', the
 type of 'testInput' should be:
 
@@ -505,16 +516,18 @@
 
 This concludes the main part of this section on \"Your first circuit\", read on
 for alternative specifications for the same 'mac' circuit, or just skip to the
-next section where we will describe another DSP classic: an FIR filter structure.
+next section where we will describe another DSP classic: an FIR filter
+structure.
 -}
 
 {- $mac5
-* __'Num' instance__:
+* __'Num' instance for 'Signal'__:
 
-    @'Signal' a@ is also also considered a 'Num'eric type as long as @a@ is also.
-    This means that we can also use the standard numeric operators, such as ('*')
-    and ('+'), directly on signals. An alternative specification of the 'mac'
-    circuit will also use the 'register' function directly:
+    @'Signal' a@ is also also considered a 'Num'eric type as long as the value
+    type /a/ is also 'Num'eric.  This means that we can also use the standard
+    numeric operators, such as ('*') and ('+'), directly on signals. An
+    alternative specification of the 'mac' circuit will also use the 'register'
+    function directly:
 
     @
     macN (x,y) = acc
@@ -522,11 +535,12 @@
         acc = register 0 (acc + x * y)
     @
 
-* __'Applicative' interface__:
+* __'Applicative' instance for 'Signal'__:
 
     We can also mix the combinational 'ma' function, with the sequential
     'register' function, by lifting the 'ma' function to the sequential 'Signal'
-    domain using the operators of the 'Applicative' type class:
+    domain using the operators ('<$>' and '<*>') of the 'Applicative' type
+    class:
 
     @
     macA (x,y) = acc
@@ -537,7 +551,8 @@
 
 * __<http://hackage.haskell.org/package/mtl/docs/Control-Monad-State-Lazy.html#t:State State> Monad__
 
-    We can also implement the original 'macT' function as a <http://hackage.haskell.org/package/mtl/docs/Control-Monad-State-Lazy.html#t:State State>
+    We can also implement the original 'macT' function as a
+    @<http://hackage.haskell.org/package/mtl/docs/Control-Monad-State-Lazy.html#t:State State>@
     monadic computation. First we must an extra import statement, right after
     the import of "CLaSH.Prelude":
 
@@ -558,6 +573,10 @@
     position of the arguments and result:
 
     @
+    asStateM :: (Pack o, Pack i)
+             => (i -> State s o)
+             -> s
+             -> (SignalP i -> SignalP o)
     asStateM f i = g \<^\> i
       where
         g s x = let (o,s') = runState (f x) s
@@ -655,22 +674,196 @@
 @
 
 Here we can finally see the advantage of having the '<^>' return a function
-of type @'SignalP' i -> 'SignalP' o@:
+of type: @('SignalP' i -> 'SignalP' o)@ (instead of:
+@('Signal' i -> 'Signal' o)@):
 
   * We can use normal pattern matching to get parts of the result, and,
   * We can use normal tuple-constructors to build the input values for the
     circuits.
 -}
 
+{- $vhdlprimitives
+There are times when you already have an existing piece of IP, or there are
+times where you need the VHDL to have a specific shape so that the VHDL
+synthesis tool can infer a specific component. In these specific cases you can
+resort to defining your own VHDL primitives. Actually, most of the primitives
+in CλaSH are specified in the same way as you will read about in this section.
+There are perhaps 10 (at most) functions which are truly hard-coded into the
+CλaSH compiler. You can take a look at the files in
+<http://github.com/christiaanb/clash2/tree/master/primitives>
+if you want to know which functions are defined as \"regular\" primitives. The
+compiler looks for primitives in two locations:
+
+* The official install location: e.g.
+  @$CABAL_DIR\/share\/\<GHC_VERSION\>\/clash-ghc\-<VERSION\>\/primitives@
+* The current directory (the location given by @pwd@)
+
+Where redefined primitives in the current directory will overwrite those in
+the official install location. For now, files containing primitive definitions
+must end in the @.json@ file-extension.
+
+CλaSH differentiates between two types of primitives, /expression/ primitives
+and /declaration/ primitives, corresponding to whether the primitive is a VHDL
+/expression/ or a VHDL /declaration/. We will first explore /expression/
+primitives, using 'Signed' multiplication ('*') as an example. The
+"CLaSH.Sized.Signed" module specifies multiplication as follows:
+
+@
+{\-# NOINLINE timesS #-\}
+timesS :: KnownNat n => Signed n -> Signed n -> Signed n
+timesS (S a) (S b) = fromIntegerS_inlineable (a * b)
+@
+
+For which the /expression/ primitive is:
+
+@
+{ \"BlackBox\" :
+  { "name"      : "CLaSH.Sized.Signed.timesS"
+  , "templateE" : "resize(~ARG[1] * ~ARG[2], ~LIT[0])"
+  }
+}
+@
+
+The @name@ of the primitive is the /fully qualified/ name of the function you
+are creating the primitive for. Because we are creating an /expression/
+primitive we define a @template__E__@ field. As the name suggest, it is a VHDL
+/template/, meaning that the compiler must fill in the holes heralded by the
+tilde (~). Here:
+
+  * @~ARG[1]@ denotes the second argument given to the @timesS@ function, which
+    corresponds to the LHS of the ('*') operator.
+  * @~ARG[2]@ denotes the third argument given to the @timesS@ function, which
+    corresponds to the RHS of the ('*') operator.
+  * @~LIT[0]@ denotes the first argument given to the @timesS@ function, with
+    the extra condition that it must be a @LIT@eral. If for some reason this
+    first argument does not turn out to be a literal then the compiler will
+    raise an error. This first arguments corresponds to the \"@'KnownNat' n@\"
+    class constraint.
+
+An extensive list with all of the template holes will be given the end of this
+section. What we immediately notice is that class constraints are counted as
+normal arguments in the primitive definition. This is because these class
+constraints are actually represented by ordinary record types, with fields
+corresponding to the methods of the type class. In the above case, 'KnownNat'
+is actually just like a @newtype@ wrapper for 'Integer'.
+
+The second kind of primitive that we will explore is the /declaration/ primitive.
+We will use 'blockRam' as an example, for which the Haskell/CλaSH code is:
+
+@
+{\-# NOINLINE blockRam #-\}
+-- | Create a blockRAM with space for \@n\@ elements
+--
+-- NB: Read value is delayed by 1 cycle
+--
+-- > 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
+         -> 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)
+  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
+             | otherwise = ram
+        o'               = ram ! r
+@
+
+And for which the /definition/ primitive is:
+
+@
+{ \"BlackBox\" :
+  { "name"      : "CLaSH.Prelude.blockRam"
+  , "templateD" :
+"~SYM[0]_block : block
+  type ram_array is array (natural range <>) of ~TYP[8];
+  signal ~SYM[1] : ram_array((~ARG[0]-1) downto 0) := (others => ~ARG[3]); -- ram
+  signal ~SYM[2] : ~TYP[8]; -- inp
+  signal ~SYM[3] : ~TYP[8] := ~ARG[3]; -- outp
+begin
+  ~SYM[2] <= ~ARG[8];
+
+  process(~CLKO)
+  begin
+    if rising_edge(~CLKO) then
+      if ~ARG[7] then
+        ~SYM[1](to_integer(~ARG[5])) <= ~SYM[2];
+      end if;
+      ~SYM[3] <= ~SYM[1](to_integer(~ARG[6]));
+    end if;
+  end process;
+
+  ~RESULT <= ~SYM[3];
+end block;"
+  }
+}
+@
+
+Again, the @name@ of the primitive is the fully qualified name of the function
+you are creating the primitive for. Because we are creating a /declaration/
+primitive we define a @template__D__@ field. Instead of discussing what the
+individual template holes mean in the above context, we will instead just give
+a general listing of the available template holes:
+
+* @~RESULT@: VHDL signal to which the result of a primitive must be assigned
+  to. NB: Only used in a /definition/ primitive.
+* @~ARG[N]@: @(N+1)@'th argument to the function.
+* @~LIT[N]@: @(N+1)@'th argument to the function An extra condition that must
+  hold is that this @(N+1)@'th argument is an (integer) literal.
+* @~CLK[N]@: Clock signal to which the @(N+1)@'th argument is synchronized to.
+* @~CLKO@: Clock signal to which the result is synchronized to.
+* @~RST[N]@: Asynchronous reset signal to the clock to which the @(N+1)@'th
+  argument is synchronized to.
+* @~RSTO@: Asynchronous reset signal to the clock to which the result is
+  synchronized to.
+* @~TYP[N]@: VHDL type of the @(N+1)@'th argument.
+* @~TYPO@: VHDL type of the result.
+* @~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.
+* @~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.
+
+Some final remarks to end this section: VHDL primitives are there to instruct the
+CλaSH compiler to use the given VHDL template, instead of trying to do normal
+synthesis. As a consequence you can use constructs inside the Haskell
+definitions that are normally not synthesizable by the CλaSH compiler. However,
+VHDL primitives do not give us /co-simulation/: where you would be able to
+simulate VHDL and Haskell in a /single/ environment. If you still want to
+simulate your design in Haskell, you will have to describe, in a cycle- and
+bit-accurate way, the behaviour of that (potentially complex) IP you are trying
+to include in your design.
+
+Perhaps in the future, someone will figure out how to connect the two simulation
+worlds, using e.g. VHDL's foreign function interface VHPI.
+-}
+
 {- $conclusion
 For now, this is the end of this tutorial. We will be adding updates over time,
-so check back from time to time. For now we recommend that you continue with
-exploring the "CLaSH.Prelude" module however, and like that hopefully get a feel
-of what CλaSH is capable of.
+so check back from time to time. For now, we recommend that you continue with
+exploring the "CLaSH.Prelude" module, and get a better understanding of the
+capabilities of CλaSH in the process.
 -}
 
 {- $errorsandsolutions
-A list often encountered errors and their solutions:
+A list of often encountered errors and their solutions:
 
 * __Type error: Couldn't match expected type ‘Signal (a,b)’ with actual type__
   __‘(Signal a, Signal b)’__:
@@ -701,7 +894,7 @@
   __ actual type ‘Signal (a,b)’__:
 
     Product types (to which tuples belong) of signals and signals of product
-    types are __isomorphic__ due to synchronisity principle, but are not
+    types are __isomorphic__ due to synchronicity principle, but are not
     (structurally) equal. Use the 'unpack' function to convert from a signal
     type to the product type. So if your code which gives the error looks like:
 
@@ -722,31 +915,54 @@
 
     NB: Use 'cunpack' when you are using explicitly clocked 'CSignal's
 
+* __CLaSH.Netlist(..): Not in normal form: \<REASON\>: \<EXPR\>__:
+
+    A function could not be transformed into the expected normal form. This
+    usually means one of the following:
+
+    * The @topEntity@ has residual polymorphism.
+    * The @topEntity@ has higher-order arguments, or a higher-order result.
+    * You are using types which cannot be represented in hardware.
+
+    The solution for all the above listed reasons is quite simple: remove them.
+    That is, make sure that the @topEntity@ is completely monomorphic and
+    first-order. Also remove any variables and constants/literals that have a
+    non-representable type, see <#unsupported Unsupported Haskell features> to
+    find out which types are not representable.
+
 * __CLaSH.Normalize(94): Expr belonging to bndr: \<FUNCTION\> remains__
   __recursive after normalization__:
 
     * If you actually wrote a recursive function, rewrite it to a non-recursive
-      one :-)
+      one using e.g. one of the higher-order functions in "CLaSH.Sized.Vector" :-)
 
     * You defined a recursively defined value, but left it polymorphic:
 
     @
     topEntity x y = acc
-    where
-      acc = register 3 (x*y + acc)
+      where
+        acc = register 3 (acc + x * y)
     @
 
     The above function, works for any number-like type. This means that @acc@ is
     a recursively defined __polymorphic__ value. Adding a monomorphic type
-    annotation makes the error go away.
+    annotation makes the error go away:
 
     @
     topEntity :: Signal (Signed 8) -> Signal (Signed 8) -> Signal (Signed 8)
     topEntity x y = acc
-    where
-      acc = register 3 (x*y + acc)
+      where
+        acc = register 3 (acc + x * y)
     @
 
+    Or, alternatively:
+
+    @
+    topEntity x y = acc
+      where
+        acc = register (3 :: Signed 8) (acc + x * y)
+    @
+
 * __CLaSH.Normalize.Transformations(155): InlineNonRep: \<FUNCTION\> already__
   __inlined 100 times in:\<FUNCTION\>, \<TYPE\>__:
 
@@ -781,12 +997,12 @@
                                 else (b,a)
     @
 
-    Will not terminate because 'vzipWith' is too strict in its left argument:
+    Will not terminate because 'vzipWith' is too strict in its second argument:
 
     >>> sortV (4 :> 1 :> 2 :> 3 :> Nil)
     <*** Exception: <<loop>>
 
-    In this case, adding 'lazyV' on 'vzipWith's left argument:
+    In this case, adding 'lazyV' on 'vzipWith's second argument:
 
     @
     sortVL xs = vmap fst sorted <: (snd (vlast sorted))
@@ -855,6 +1071,62 @@
 
   [@Floating point types@]
 
-    There is no support for the 'Float' and 'Double' type, if you need numbers
+    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@]
+
+    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.
+
+    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, which can only represent 32-bit integer values. Use these types with
+    due diligence.
+
+  [@Side-effects: 'IO', <http://hackage.haskell.org/package/base/docs/Control-Monad-ST.html#t:ST ST>, etc.@]
+
+    There is no support for side-effecting computations such as those in the
+    'IO' or @<http://hackage.haskell.org/package/base/docs/Control-Monad-ST.html#t:ST ST>@
+    monad. There is also no support for Haskell's
+    <http://www.haskell.org/haskellwiki/Foreign_Function_Interface FFI>.
+-}
+
+{- $vslava
+In Haskell land the most well-known way of describing digital circuits is the
+Lava family of languages:
+
+* <http://hackage.haskell.org/package/chalmers-lava2000 Chalmers Lava>
+* <http://hackage.haskell.org/package/xilinx-lava Xilinx Lava>
+* <http://hackage.haskell.org/package/york-lava York Lava>
+* <http://hackage.haskell.org/package/kansas-lava Kansas Lava>
+
+The big difference between CλaSH and Lava is that CλaSH uses a \"standard\"
+compiler (static analysis) approach towards synthesis, where Lava is an
+embedded domain specific language. One downside of static analysis vs. the
+embedded language approach is already clearly visible: synthesis of recursive
+descriptions does not come for \"free\". This will be implemented in CλaSH in
+due time, but that doesn't help the circuit designer right now. As already
+mentioned earlier, the lack of support for recursive functions is amortized by
+the built-in support for the higher-order in "CLaSH.Sized.Vector".
+
+The big upside of CλaSH and its static analysis approach is that CλaSH can
+do synthesis of \"normal\" functions: there is no forced encasing datatype (often
+called /Signal/ in Lava) on all the arguments and results of a synthesizable
+function. This enables the following features not available to Lava:
+
+* Automatic synthesis for user-defined ADTs
+* 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.
+
+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\"
+and / or easy to use as the standard Haskell features.
 -}
