diff --git a/hardware-edsl.cabal b/hardware-edsl.cabal
--- a/hardware-edsl.cabal
+++ b/hardware-edsl.cabal
@@ -1,5 +1,5 @@
 name:                hardware-edsl
-version:             0.1.2
+version:             0.1.5
 synopsis:            Deep embedding of hardware descriptions with code generation.
 description:         Deep embedding of hardware descriptions with code generation.
 license:             BSD3
@@ -28,6 +28,7 @@
     Language.Embedded.Hardware.Expression.Represent.Bit,
     Language.Embedded.Hardware.Expression.Syntax,
     Language.Embedded.Hardware.Interface,
+    Language.Embedded.Hardware.Interface.AXI
     Language.Embedded.Hardware.Command,
     Language.Embedded.Hardware.Command.Backend.VHDL,
     Language.Embedded.Hardware.Command.CMD,
@@ -37,7 +38,6 @@
     Language.Embedded.VHDL.Monad.Type,
     Language.Embedded.VHDL.Monad.Expression
     Language.Embedded.VHDL.Monad.Util
---    Language.Embedded.Hardware.Common.AXI
 
   --other-modules:
     
diff --git a/src/Language/Embedded/Hardware/Command.hs b/src/Language/Embedded/Hardware/Command.hs
--- a/src/Language/Embedded/Hardware/Command.hs
+++ b/src/Language/Embedded/Hardware/Command.hs
@@ -4,17 +4,22 @@
 {-# LANGUAGE TypeOperators       #-}
 {-# LANGUAGE ConstraintKinds     #-}
 
+{-# LANGUAGE GADTs #-}
+
 module Language.Embedded.Hardware.Command
-  ( compile
+  (
+  -- Regular hardware compilers.
+    compile
   , icompile
   , runIO
-
+  -- AXI compilers.
+  , compileAXILite
+  , icompileAXILite
+  -- compilers that wraps a program in a dummy entity.
   , compileWrap
   , icompileWrap
-  , runIOWrap
-
+  
   , VHDL.Mode(..)
-
   , module CMD
   , module Language.Embedded.Hardware.Command.CMD
   , module Language.Embedded.Hardware.Command.Frontend
@@ -26,6 +31,7 @@
 import Language.Embedded.Hardware.Command.Frontend
 import Language.Embedded.Hardware.Command.Backend.VHDL
 import Language.Embedded.Hardware.Interface
+import Language.Embedded.Hardware.Interface.AXI
 
 import Language.Embedded.VHDL (VHDL, prettyVHDL)
 
@@ -34,6 +40,8 @@
 
 import Control.Monad.Operational.Higher
 
+import Control.Monad.Identity
+
 import qualified GHC.Exts as GHC (Constraint)
 
 --------------------------------------------------------------------------------
@@ -69,7 +77,29 @@
 runIO = interpretBi (return . evalE)
 
 --------------------------------------------------------------------------------
+-- Some extra compilers that might be handy to have.
 
+compileAXILite :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .
+  ( Interp instr VHDL (Param2 exp pred)
+  , HFunctor instr
+  , AXIPred instr exp pred
+  )
+  => Comp instr exp pred Identity a
+  -> String
+compileAXILite = compile . void . component . axi_light 
+
+icompileAXILite :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .
+  ( Interp instr VHDL (Param2 exp pred)
+  , HFunctor instr
+  , AXIPred instr exp pred
+  )
+  => Comp instr exp pred Identity a
+  -> IO ()
+icompileAXILite = putStrLn . compileAXILite
+
+--------------------------------------------------------------------------------
+-- todo: Not sure we need these any more.
+
 compileWrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .
      ( Interp instr VHDL (Param2 exp pred)
      , HFunctor instr
@@ -93,21 +123,6 @@
   => (Signal Bool -> Signal Bool -> Program instr (Param2 exp pred) ())
   -> IO ()
 icompileWrap = icompile . wrap
-
-runIOWrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a
-   . ( InterpBi instr IO (Param1 pred)
-     , HBifunctor instr
-     , EvaluateExp exp
-     , ComponentCMD  :<: instr
-     , StructuralCMD :<: instr
-     , SignalCMD     :<: instr
-     , pred Bool
-     )
-  => (Signal Bool -> Signal Bool -> Program instr (Param2 exp pred) ())
-  -> IO ()
-runIOWrap = runIO . wrap
-
---------------------------------------------------------------------------------
 
 -- | Wrap a hardware program in a architecture/entity pair.
 wrap :: forall instr (exp :: * -> *) (pred :: * -> GHC.Constraint) a .
diff --git a/src/Language/Embedded/Hardware/Command/Backend/VHDL.hs b/src/Language/Embedded/Hardware/Command/Backend/VHDL.hs
--- a/src/Language/Embedded/Hardware/Command/Backend/VHDL.hs
+++ b/src/Language/Embedded/Hardware/Command/Backend/VHDL.hs
@@ -37,42 +37,33 @@
 -- * Translation of hardware commands into VHDL.
 --------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------
--- ** ...
-
-evalEM :: forall exp a . EvaluateExp exp => Maybe (exp a) -> a
-evalEM e = maybe (error "empty value") id $ fmap evalE e
-
-compEM :: forall exp a . CompileExp exp => Maybe (exp a) -> VHDL (Maybe V.Expression)
-compEM e = maybe (return Nothing) (>>= return . Just) $ fmap compE e
-
---------------------------------------------------------------------------------
--- ** ...
-
 class CompileType ct
   where
     compileType :: ct a => proxy1 ct -> proxy2 a -> VHDL V.Type
     compileLit  :: ct a => proxy1 ct ->        a -> VHDL V.Expression
     compileBits :: ct a => proxy1 ct ->        a -> VHDL V.Expression
 
-instance CompileType HType
+instance CompileType PrimType
   where
     compileType _ = compT
-    compileLit  _ = return . literal . printVal
-    compileBits _ = return . literal . printBits
+    compileLit  _ = return . literal . primTypeVal
+    compileBits _ = return . literal . primTypeBits
 
 --------------------------------------------------------------------------------
 
-compT :: HType a => proxy a -> VHDL V.Type
-compT = declare
+compT :: forall proxy a . PrimType a => proxy a -> VHDL V.Type
+compT _ = declareType (Proxy :: Proxy a)
 
-compTM :: forall proxy ct exp a . (CompileType ct, ct a) => proxy ct -> Maybe (exp a) -> VHDL V.Type
+compTM :: forall proxy ct exp a . (CompileType ct, ct a)
+  => proxy ct -> Maybe (exp a) -> VHDL V.Type
 compTM _ _ = compileType (Proxy::Proxy ct) (Proxy::Proxy a)
 
-compTF :: forall proxy ct exp a b . (CompileType ct, ct a) => proxy ct -> (exp a -> b) -> VHDL V.Type
+compTF :: forall proxy ct exp a b . (CompileType ct, ct a)
+  => proxy ct -> (exp a -> b) -> VHDL V.Type
 compTF _ _ = compileType (Proxy::Proxy ct) (Proxy::Proxy a)
 
-compTA :: forall proxy ct array i a . (CompileType ct, ct a) => proxy ct -> V.Range -> array a -> VHDL V.Type
+compTA :: forall proxy ct array i a . (CompileType ct, ct a)
+  => proxy ct -> V.Range -> array a -> VHDL V.Type
 compTA _ range _ =
   do i <- newSym (Base "array")
      t <- compileType (Proxy::Proxy ct) (Proxy::Proxy a)
@@ -92,6 +83,16 @@
 
 --------------------------------------------------------------------------------
 
+evalEM :: forall exp a . EvaluateExp exp
+  => Maybe (exp a) -> a
+evalEM e = maybe (error "empty value") id $ fmap evalE e
+
+compEM :: forall exp a . CompileExp exp
+  => Maybe (exp a) -> VHDL (Maybe V.Expression)
+compEM e = maybe (return Nothing) (>>= return . Just) $ fmap compE e
+
+--------------------------------------------------------------------------------
+
 proxyE :: exp a -> Proxy a
 proxyE _ = Proxy
 
@@ -102,12 +103,7 @@
 proxyF _ = Proxy
 
 --------------------------------------------------------------------------------
--- ** ...
 
-newSym :: Name -> VHDL String
-newSym (Base  n) = V.newSym n
-newSym (Exact n) = return   n
-
 freshVar :: forall proxy ct exp a . (CompileType ct, ct a)
   => proxy ct -> Name -> VHDL (Val a)
 freshVar _ prefix =
@@ -116,8 +112,26 @@
      V.variable (ident' i) t Nothing
      return (ValC i)
 
+newSym :: Name -> VHDL String
+newSym (Base  n) = V.newSym n
+newSym (Exact n) = return   n
+
+ident :: ToIdent a => a -> String
+ident a = let (Ident s) = toIdent a in s
+
+ident' :: ToIdent a => a -> V.Identifier
+ident' a = V.Ident $ ident a
+
+-- todo: this... why does this work?
+instance ToIdent String where toIdent = Ident
+instance ToIdent Ident  where toIdent = id
+instance ToIdent Name   where
+  toIdent (Base s)  = Ident s
+  toIdent (Exact s) = Ident s
+
 --------------------------------------------------------------------------------
 -- ** Signals.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp SignalCMD VHDL (Param2 exp ct)
   where
@@ -160,6 +174,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Variables.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp VariableCMD VHDL (Param2 exp ct)
   where
@@ -200,6 +215,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Constants.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp ConstantCMD VHDL (Param2 exp ct)
   where
@@ -225,6 +241,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Arrays.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp ArrayCMD VHDL (Param2 exp ct)
   where
@@ -278,6 +295,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Virtual Arrays.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp VArrayCMD VHDL (Param2 exp ct)
   where
@@ -361,6 +379,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Loops.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp LoopCMD VHDL (Param2 exp ct)
   where
@@ -402,6 +421,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Conditional.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp ConditionalCMD VHDL (Param2 exp ct)
   where
@@ -456,6 +476,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Components.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp ComponentCMD VHDL (Param2 exp ct)
   where
@@ -524,6 +545,7 @@
 
 --------------------------------------------------------------------------------
 -- ** Structural.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp StructuralCMD VHDL (Param2 exp ct)
   where
@@ -552,6 +574,7 @@
 
 --------------------------------------------------------------------------------
 -- ** VHDL.
+--------------------------------------------------------------------------------
 
 instance (CompileExp exp, CompileType ct) => Interp VHDLCMD VHDL (Param2 exp ct)
   where
@@ -616,26 +639,7 @@
 runVHDL = error "hardware-edsl.runVHDL: todo."
 
 --------------------------------------------------------------------------------
--- Helpers.
---
--- todo : make a lift that first tries to go backwards. If that's not possible,
---        perform a regular lift. This should get rid of most extra parenthesis.
 
-ident :: ToIdent a => a -> String
-ident a = let (Ident s) = toIdent a in s
-
-ident' :: ToIdent a => a -> V.Identifier
-ident' a = V.Ident $ ident a
-
--- todo: this... why does this work?
-instance ToIdent String where toIdent = Ident
-instance ToIdent Ident  where toIdent = id
-instance ToIdent Name   where
-  toIdent (Base s)  = Ident s
-  toIdent (Exact s) = Ident s
-
---------------------------------------------------------------------------------
-
 simple   :: String -> V.Name
 simple   s = V.simple s
 
@@ -654,13 +658,9 @@
 slice'   :: String -> V.Range -> V.Expression
 slice'   s = lift . V.name . slice s
 
---------------------------------------------------------------------------------
-
 literal :: String -> V.Expression
 literal s = lift $ V.literal $ V.number s
 
---------------------------------------------------------------------------------
-
 range  :: V.Expression -> V.Direction -> V.Expression -> V.Range
 range l dir r = V.range (unpackSimple l) dir (unpackSimple r)
 
@@ -671,7 +671,6 @@
 rangePoint a = V.range (V.point $ toInteger a) V.downto (V.point 0)
 
 --------------------------------------------------------------------------------
--- ...
 
 unpackShift :: V.Expression -> V.ShiftExpression
 unpackShift (V.ENand (V.Relation s Nothing) Nothing) = s
@@ -685,24 +684,4 @@
 unpackTerm (V.ENand (V.Relation (V.ShiftExpression (V.SimpleExpression Nothing t []) Nothing) Nothing) Nothing) = t
 unpackTerm e = lift e
 
---------------------------------------------------------------------------------
-
-
---------------------------------------------------------------------------------
-{-
-ident :: String -> V.Identifier
-ident s = V.Ident s
-
-ident' :: Name -> V.Identifier
-ident' (Base  n) = ident n
-ident' (Exact n) = ident n
-
-name :: String -> V.Primary
-name = V.PrimName . V.NSimple . ident
--}
---------------------------------------------------------------------------------
-{-
-fromIdent :: ToIdent a => a -> V.Identifier
-fromIdent a = let (Ident i) = toIdent a in ident i
--}
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Command/CMD.hs b/src/Language/Embedded/Hardware/Command/CMD.hs
--- a/src/Language/Embedded/Hardware/Command/CMD.hs
+++ b/src/Language/Embedded/Hardware/Command/CMD.hs
@@ -15,7 +15,7 @@
 
 import Language.Embedded.VHDL (Mode)
 import Language.Embedded.Hardware.Interface
-import Language.Embedded.Hardware.Expression.Represent (Inhabited, Sized)
+import Language.Embedded.Hardware.Expression.Represent (PrimType, Inhabited, Sized)
 import Language.Embedded.Hardware.Expression.Represent.Bit (Bit, Bits)
 
 import Control.Monad.Reader (ReaderT(..), runReaderT, lift)
@@ -411,11 +411,11 @@
 data Signature fs a
   where
     Ret  :: prog () -> Signature (Param3 prog exp pred) ()
-    SSig :: (pred a, Inhabited a, Sized a)
+    SSig :: (pred a, Integral a, PrimType a)
       => Name -> Mode
       -> (Signal a -> Signature (Param3 prog exp pred) b)
       -> Signature (Param3 prog exp pred) (Signal a -> b)
-    SArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i)
+    SArr :: (pred a, Integral a, PrimType a, pred i, Integral i, Ix i)
       => Name -> Mode -> i
       -> (Array i a -> Signature (Param3 prog exp pred) b)
       -> Signature (Param3 prog exp pred) (Array i a -> b)
@@ -443,11 +443,11 @@
 data Argument pred a
   where
     Nil  :: Argument pred ()
-    ASig :: (pred a, Inhabited a, Sized a)
+    ASig :: (pred a, Integral a, PrimType a)
       => Signal a
       -> Argument pred b
       -> Argument pred (Signal a -> b)
-    AArr :: (pred a, Inhabited a, Sized a, Integral i, Ix i)
+    AArr :: (pred a, Integral a, PrimType a, pred i, Integral i, Ix i)
       => Array i a
       -> Argument pred b
       -> Argument pred (Array i a -> b)
diff --git a/src/Language/Embedded/Hardware/Command/Frontend.hs b/src/Language/Embedded/Hardware/Command/Frontend.hs
--- a/src/Language/Embedded/Hardware/Command/Frontend.hs
+++ b/src/Language/Embedded/Hardware/Command/Frontend.hs
@@ -20,6 +20,7 @@
 import Data.IORef (readIORef)
 import Data.Int
 import Data.Word
+import Data.Typeable
 
 import System.IO.Unsafe -- used for `veryUnsafeFreezeVariable`.
 
@@ -401,43 +402,63 @@
 
 --------------------------------------------------------------------------------
 
-exactInput  :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+exactInput  :: (pred a, Integral a, PrimType a)
+  => String
+  -> (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 exactInput  n = SSig (Exact n) In
 
-namedInput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+namedInput :: (pred a, Integral a, PrimType a)
+  => String
+  -> (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 namedInput n = SSig (Base n) In
 
-input :: (pred a, Inhabited a, Sized a) => (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+input :: (pred a, Integral a, PrimType a)
+  => (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 input = namedInput "in"
 
-exactInputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+{-
+exactInputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 exactInputArr n l = SArr (Exact n) In l
 
-namedInputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+namedInputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 namedInputArr n l = SArr (Base n) In l
 
-inputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+inputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 inputArr = namedInputArr "in"
+-}
 
-exactOutput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+exactOutput :: (pred a, Integral a, PrimType a)
+  => String
+  -> (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 exactOutput n = SSig (Exact n) Out
 
-namedOutput :: (pred a, Inhabited a, Sized a) => String -> (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+namedOutput :: (pred a, Integral a, PrimType a)
+  => String
+  -> (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 namedOutput n = SSig (Base n) Out
 
-output :: (pred a, Inhabited a, Sized a) => (Signal a -> Sig instr exp pred m b) -> Sig instr exp pred m (Signal a -> b)
+output :: (pred a, Integral a, PrimType a)
+  => (Signal a -> Sig instr exp pred m b)
+  -> Sig instr exp pred m (Signal a -> b)
 output = namedOutput "out"
 
-exactOutputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+{-
+exactOutputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 exactOutputArr n l = SArr (Exact n) Out l
 
-namedOutputArr :: (pred a, Inhabited a, Sized a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+namedOutputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => String -> i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 namedOutputArr n l = SArr (Base n) Out l
 
-outputArr :: (pred a, Inhabited a, pred i, Sized a, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
+outputArr :: (pred a, Inhabited a, Sized a, Integral a, Rep a, Typeable a, pred i, Integral i, Ix i) => i -> (Array i a -> Sig instr exp pred m b) -> Sig instr exp pred m (Array i a -> b)
 outputArr = namedOutputArr "out"
+-}
 
-ret :: (ProgramT instr (Param2 exp pred) m) () -> Signature (Param3 (ProgramT instr (Param2 exp pred) m) exp pred) ()
+ret :: ProgramT instr (Param2 exp pred) m () -> Sig instr exp pred m ()
 ret = Ret
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Expression.hs b/src/Language/Embedded/Hardware/Expression.hs
--- a/src/Language/Embedded/Hardware/Expression.hs
+++ b/src/Language/Embedded/Hardware/Expression.hs
@@ -2,11 +2,8 @@
   ( HExp
   , HType
   , module Language.Embedded.Hardware.Expression.Frontend
-  , module Language.Embedded.Hardware.Expression.Represent.Bit
   ) where
 
-import Language.Embedded.Hardware.Expression.Syntax (HExp)
+import Language.Embedded.Hardware.Expression.Syntax (HExp, HType)
 import Language.Embedded.Hardware.Expression.Frontend
-import Language.Embedded.Hardware.Expression.Represent (HType)
-import Language.Embedded.Hardware.Expression.Represent.Bit
 import Language.Embedded.Hardware.Expression.Backend.VHDL ()
diff --git a/src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs b/src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs
--- a/src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs
+++ b/src/Language/Embedded/Hardware/Expression/Backend/VHDL.hs
@@ -29,7 +29,7 @@
 
 instance FreeExp HExp
   where
-    type PredicateExp HExp = HType
+    type PredicateExp HExp = PrimType
     litE = value
     varE = var
 
@@ -52,11 +52,13 @@
   where
     compE  = compHExp
 
-compHType :: forall a . HType a => HExp a -> VHDL VHDL.Type
-compHType _ = declare (undefined :: proxy a)
+compHType :: forall a . PrimType a
+  => HExp a -> VHDL VHDL.Type
+compHType _ = declareType (Proxy :: Proxy a)
 
-compHTypeFun :: forall a b . (HType a, HType b) => (a -> b) -> VHDL VHDL.Type
-compHTypeFun _ = declare (undefined :: proxy a)
+compHTypeFun :: forall a b . (PrimType a, PrimType b)
+  => (a -> b) -> VHDL VHDL.Type
+compHTypeFun _ = declareType (Proxy :: Proxy a)
 
 compHExp :: forall a . HExp a -> VHDL VHDL.Expression
 compHExp e = Hoist.lift <$> compSimple e
@@ -69,7 +71,7 @@
 
     compDomain
       :: forall sig
-       . HType (DenResult sig)
+       . PrimType (DenResult sig)
       => Dom sig
       -> Args (AST T) sig
       -> VHDL Kind
@@ -172,12 +174,16 @@
           x' <- Hoist.lift <$> compLoop x
           return $ Hoist.E $ VHDL.uCast x' tf tt
     compDomain primary args
-      | Just (Name n)       <- prj primary = return $ Hoist.P $ VHDL.name n
-      | Just (Literal i)    <- prj primary = return $ Hoist.P $ VHDL.literal $ VHDL.number $ printVal i
-      | Just (Aggregate a)  <- prj primary = return $ Hoist.P $ VHDL.aggregate a
+      | Just (Name n)       <- prj primary =
+          return $ Hoist.P $ VHDL.name n
+      | Just (Literal i)    <- prj primary =
+          return $ Hoist.P $ VHDL.literal $ VHDL.number $ primTypeVal i
+      | Just (Aggregate a)  <- prj primary =
+          return $ Hoist.P $ VHDL.aggregate a
       | Just (Function f _) <- prj primary = do
           as <- sequence $ listArgs compLoop args
           return $ Hoist.P $ VHDL.function (VHDL.simple f) (fmap Hoist.lift as)
-      | Just (Allocator)    <- prj primary = error "expression-backend: todo"
+      | Just (Allocator)    <- prj primary =
+          error "expression-backend-todo: allocators."
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Expression/Frontend.hs b/src/Language/Embedded/Hardware/Expression/Frontend.hs
--- a/src/Language/Embedded/Hardware/Expression/Frontend.hs
+++ b/src/Language/Embedded/Hardware/Expression/Frontend.hs
@@ -7,11 +7,9 @@
 
 import qualified Language.VHDL as V
 
-import Language.Embedded.Hardware.Interface
-import Language.Embedded.Hardware.Expression.Syntax hiding (Term, Factor, Primary)
-import Language.Embedded.Hardware.Expression.Hoist
-import Language.Embedded.Hardware.Expression.Represent
-import Language.Embedded.Hardware.Expression.Represent.Bit
+import Language.Embedded.Hardware.Expression.Syntax (HExp, HType, sugarT)
+import Language.Embedded.Hardware.Expression.Represent.Bit (Bits, bitFromInteger, bitToInteger)
+import qualified Language.Embedded.Hardware.Expression.Syntax as H
 import qualified Language.Embedded.VHDL.Monad.Expression as V
 
 import Data.Typeable (Typeable)
@@ -51,31 +49,31 @@
 instance Expr HExp where
   true  = value True
   false = value False
-  and   = sugarT And
-  or    = sugarT Or
-  xor   = sugarT Xor
-  xnor  = sugarT Xnor
-  nand  = sugarT Nand
-  nor   = sugarT Nor
+  and   = sugarT H.And
+  or    = sugarT H.Or
+  xor   = sugarT H.Xor
+  xnor  = sugarT H.Xnor
+  nand  = sugarT H.Nand
+  nor   = sugarT H.Nor
 
 --------------------------------------------------------------------------------
 
 -- | Relational operators.
 class Rel exp where
-  eq  :: (HType a, Eq a) => exp a -> exp a -> exp Bool
-  neq :: (HType a, Eq a) => exp a -> exp a -> exp Bool
+  eq  :: (HType a, Eq a)  => exp a -> exp a -> exp Bool
+  neq :: (HType a, Eq a)  => exp a -> exp a -> exp Bool
   lt  :: (HType a, Ord a) => exp a -> exp a -> exp Bool
   lte :: (HType a, Ord a) => exp a -> exp a -> exp Bool
   gt  :: (HType a, Ord a) => exp a -> exp a -> exp Bool
   gte :: (HType a, Ord a) => exp a -> exp a -> exp Bool
 
 instance Rel HExp where
-  eq  = sugarT Eq
-  neq = sugarT Neq
-  lt  = sugarT Lt
-  lte = sugarT Lte
-  gt  = sugarT Gt
-  gte = sugarT Gte
+  eq  = sugarT H.Eq
+  neq = sugarT H.Neq
+  lt  = sugarT H.Lt
+  lte = sugarT H.Lte
+  gt  = sugarT H.Gt
+  gte = sugarT H.Gte
 
 --------------------------------------------------------------------------------
 
@@ -89,12 +87,12 @@
   ror :: (HType a, B.Bits a) => exp a -> exp Integer -> exp a
 
 instance Shift HExp where
-  sll = sugarT Sll
-  srl = sugarT Srl
-  sla = sugarT Sla
-  sra = sugarT Sra
-  rol = sugarT Rol
-  ror = sugarT Ror
+  sll = sugarT H.Sll
+  srl = sugarT H.Srl
+  sla = sugarT H.Sla
+  sra = sugarT H.Sra
+  rol = sugarT H.Rol
+  ror = sugarT H.Ror
 
 --------------------------------------------------------------------------------
 
@@ -103,14 +101,14 @@
   neg :: (HType a, Num a) => exp a -> exp a
   add :: (HType a, Num a) => exp a -> exp a -> exp a
   sub :: (HType a, Num a) => exp a -> exp a -> exp a
-  cat :: ( KnownNat n, KnownNat m, KnownNat (n + m), Typeable (n + m))
+  cat :: (KnownNat n, KnownNat m, KnownNat (n + m), Typeable (n + m))
       => exp (Bits n) -> exp (Bits m) -> exp (Bits (n + m))
 
 instance Simple HExp where
-  neg = sugarT Neg
-  add = sugarT Add
-  sub = sugarT Sub
-  cat = sugarT Cat
+  neg = sugarT H.Neg
+  add = sugarT H.Add
+  sub = sugarT H.Sub
+  cat = sugarT H.Cat
 
 --------------------------------------------------------------------------------
 
@@ -122,10 +120,10 @@
   rem :: (HType a, Integral a) => exp a -> exp a -> exp a
 
 instance Term HExp where
-  mul = sugarT Mul
-  div = sugarT Div
-  mod = sugarT Mod
-  rem = sugarT Rem
+  mul = sugarT H.Mul
+  div = sugarT H.Div
+  mod = sugarT H.Mod
+  rem = sugarT H.Rem
 
 --------------------------------------------------------------------------------
 
@@ -136,9 +134,9 @@
   not :: exp Bool -> exp Bool
 
 instance Factor HExp where
-  exp = sugarT Exp
-  abs = sugarT Abs
-  not = sugarT Not
+  exp = sugarT H.Exp
+  abs = sugarT H.Abs
+  not = sugarT H.Not
 
 --------------------------------------------------------------------------------
 
@@ -149,33 +147,37 @@
   cast  :: (HType a, HType b) => (a -> b) -> exp a -> exp b
   
 instance Primary HExp where
-  value  = sugarT . Literal
-  name n = sugarT (Name (V.NSimple (V.Ident n)))
-  cast f = sugarT (Conversion f)
+  value  = sugarT . H.Literal
+  name n = sugarT (H.Name (V.NSimple (V.Ident n)))
+  cast f = sugarT (H.Conversion f)
 
 -- | Creates a variable from a string.
 var :: (Primary exp, HType a) => String -> exp a
 var = name
 
 -- | Converts an integral (signed/unsigned/integer) to an integer.
-toInteger :: (Primary exp, HType a, Integral a) => exp a -> exp Integer
+toInteger :: (Primary exp, HType a, Integral a)
+  => exp a -> exp Integer
 toInteger = cast (fromIntegral)
 
 -- | Converts an integral to a signed value.
-toSigned :: (Primary exp, HType a, HType b, Integral a, Num b) => exp a -> exp b
+toSigned :: (Primary exp, HType a, HType b, Integral a, Num b)
+  => exp a -> exp b
 toSigned = cast (fromIntegral)
 
 -- | Converts an integral to a unsigned value.
-toUnsigned :: (Primary exp, HType a, HType b, Integral a, Num b) => exp a -> exp b
+toUnsigned :: (Primary exp, HType a, HType b, Integral a, Num b)
+  => exp a -> exp b
 toUnsigned = cast (fromIntegral)
 
 -- | Converts an integral to its bit representation.
-toBits :: (Primary exp, HType a, HType (Bits b), Integral a, KnownNat b) => exp a -> exp (Bits b)
+toBits :: (Primary exp, HType a, Integral a, KnownNat b)
+  => exp a -> exp (Bits b)
 toBits = cast (bitFromInteger . fromIntegral)
 
---------------------------------------------------------------------------------
-
-fromBits :: (Primary exp, HType (Bits a), HType b, Num b, KnownNat a) => exp (Bits a) -> exp b
+-- | Converts a bit representation of integral into its original form.
+fromBits :: (Primary exp, HType b, Num b, KnownNat a)
+  => exp (Bits a) -> exp b
 fromBits = cast (fromIntegral . bitToInteger)
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Expression/Represent.hs b/src/Language/Embedded/Hardware/Expression/Represent.hs
--- a/src/Language/Embedded/Hardware/Expression/Represent.hs
+++ b/src/Language/Embedded/Hardware/Expression/Represent.hs
@@ -1,143 +1,29 @@
+{-# LANGUAGE GADTs                #-}
 {-# LANGUAGE FlexibleInstances    #-}
 {-# LANGUAGE UndecidableInstances #-}
 {-# LANGUAGE ScopedTypeVariables  #-}
-
-module Language.Embedded.Hardware.Expression.Represent
-  ( Rep(..)
-  , Inhabited(..)
-  , Sized(..)
-  , HType(..)
-  
-  , declareBoolean
-  , declareNumeric
-  , declareFloating
-    
-  , module Data.Int
-  , module Data.Word
-  ) where
+{-# LANGUAGE StandaloneDeriving   #-}
 
-import qualified Language.VHDL as V
+module Language.Embedded.Hardware.Expression.Represent where
 
-import Language.VHDL (Expression)
+import Language.Embedded.Hardware.Expression.Represent.Bit
 
 import Language.Embedded.VHDL (VHDL)
 import Language.Embedded.VHDL.Monad (newSym, newLibrary, newImport)
 import Language.Embedded.VHDL.Monad.Type
-import qualified Language.Embedded.VHDL.Monad.Util as Util (printBits)
-
-import Language.Embedded.Hardware.Expression.Hoist (lift)
+import Language.Embedded.VHDL.Monad.Util (printBits)
 
 import Data.Char (isDigit)
 import Data.Int
 import Data.Word
-import Data.Typeable
-import Text.Printf
-
---------------------------------------------------------------------------------
--- * Representation of types.
---------------------------------------------------------------------------------
+import Data.Proxy (Proxy(..))
+import Data.Typeable (Typeable)
 
--- | Collection of required classes for hardware expressions.
-class    (Typeable a, Rep a, Eq a) => HType a
-instance (Typeable a, Rep a, Eq a) => HType a
+import GHC.TypeLits
 
 --------------------------------------------------------------------------------
--- ** Representable types.
-
--- | 'Rep'resentable types.
-class Rep a
-  where
-    declare   :: proxy a -> VHDL Type
-    printVal  :: a -> String
-    printBits :: a -> String
-
-instance Rep Bool where
-  declare  _     = declareBoolean >> return std_logic
-  printVal True  = "\'1\'"
-  printVal False = "\'0\'"
-  printBits      = printVal
-
-instance Rep Int8 where
-  declare _ = declareNumeric >> return signed8
-  printVal  = show
-  printBits = Util.printBits 8
-
-instance Rep Int16 where
-  declare _ = declareNumeric >> return signed16
-  printVal  = show
-  printBits = Util.printBits 16
-
-instance Rep Int32 where
-  declare _ = declareNumeric >> return signed32
-  printVal  = show
-  printBits = Util.printBits 32
-
-instance Rep Int64 where
-  declare _ = declareNumeric >> return signed64
-  printVal  = show
-  printBits = Util.printBits 64
-
-instance Rep Word8 where
-  declare _ = declareNumeric >> return usigned8
-  printVal  = show
-  printBits = Util.printBits 8
-
-instance Rep Word16 where
-  declare _ = declareNumeric >> return usigned16
-  printVal  = show
-  printBits = Util.printBits 16
-
-instance Rep Word32 where
-  declare _ = declareNumeric >> return usigned32
-  printVal  = show
-  printBits = Util.printBits 32
-
-instance Rep Word64 where
-  declare _ = declareNumeric >> return usigned64
-  printVal  = show
-  printBits = Util.printBits 64
-
-instance Rep Int where
-  declare _ = return (integer Nothing)
-  printVal  = show
-  printBits = error "hardware-edsl.printBits: int."
-
-instance Rep Integer where
-  declare _ = return (integer Nothing)
-  printVal  = show
-  printBits = error "hardware-edsl.printBits: integer."
-
-instance Rep Float where
-  declare _ = declareFloating >> return float
-  printVal  = show
-  printBits = error "hardware-edsl.printBits: float."
-
-instance Rep Double where
-  declare _ = declareFloating >> return double
-  printVal  = show
-  printBits = error "hardware-edsl.printBits: double."
-
--- | Declare the necessary libraries to support boolean operations.
-declareBoolean :: VHDL ()
-declareBoolean =
-  do newLibrary "IEEE"
-     newImport  "IEEE.std_logic_1164"
-
--- | Declare the necessary libraries to support numerical operations.
-declareNumeric :: VHDL ()
-declareNumeric =
-  do newLibrary "IEEE"
-     newImport  "IEEE.std_logic_1164"
-     newImport  "IEEE.numeric_std"
-
--- | Declare the necessary libraries to support floating point operations.
-declareFloating :: VHDL ()
-declareFloating =
-  do newLibrary "IEEE"
-     newImport  "IEEE.float_pkg"
-
+-- * Inhabited types.
 --------------------------------------------------------------------------------
--- ** Inhabited types.
 
 -- | Inhabited types, that is, types with a base element.
 class Inhabited a
@@ -159,8 +45,13 @@
 instance Inhabited Float   where reset = 0
 instance Inhabited Double  where reset = 0
 
+instance forall n . KnownNat n => Inhabited (Bits n)
+  where
+    reset = bitFromInteger 0
+
 --------------------------------------------------------------------------------
--- ** Sized types.
+-- * Sized types.
+--------------------------------------------------------------------------------
 
 -- | Types with a known size.
 class Sized a
@@ -177,18 +68,158 @@
 instance Sized Word16  where bits _ = 16
 instance Sized Word32  where bits _ = 32
 instance Sized Word64  where bits _ = 64
+instance Sized Int     where bits _ = 32
+instance Sized Integer where bits _ = 64
+instance Sized Float   where bits _ = 32
+instance Sized Double  where bits _ = 64
 
+instance forall n . KnownNat n => Sized (Bits n)
+  where
+    bits _ = ni (Proxy :: Proxy n)
+
 --------------------------------------------------------------------------------
--- ** Hmm...
+-- * Representable types.
+--------------------------------------------------------------------------------
 
-instance Num Bool where
-  (+)    = error "(+) not implemented for Bool"
-  (-)    = error "(-) not implemented for Bool"
-  (*)    = error "(*) not implemented for Bool"
-  abs    = id
-  signum = id
-  fromInteger 0 = False
-  fromInteger 1 = True
-  fromInteger _ = error "bool-num: >1"  
+-- | Representation of primitive hardware types.
+data TypeRep a
+  where
+    -- booleans.
+    BoolT    :: TypeRep Bool
+    -- signed numbers.
+    Int8T    :: TypeRep Int8
+    Int16T   :: TypeRep Int16
+    Int32T   :: TypeRep Int32
+    Int64T   :: TypeRep Int64
+    -- unsigned numbers.
+    Word8T   :: TypeRep Word8
+    Word16T  :: TypeRep Word16
+    Word32T  :: TypeRep Word32
+    Word64T  :: TypeRep Word64
+    -- integers.
+    IntT     :: TypeRep Int
+    IntegerT :: TypeRep Integer
+    -- floating point numbers.
+    FloatT   :: TypeRep Float
+    DoubleT  :: TypeRep Double
+    -- variable sized bit values (todo).
+    BitsT    :: KnownNat n => TypeRep (Bits n)
+
+deriving instance Eq       (TypeRep a)
+deriving instance Show     (TypeRep a)
+deriving instance Typeable (TypeRep a)
+
+--------------------------------------------------------------------------------
+
+-- | Primitive hardware types.
+class (Eq a, Show a, Typeable a, Inhabited a, Sized a) => PrimType a
+  where
+    typeRep :: TypeRep a
+
+instance PrimType Bool    where typeRep = BoolT
+instance PrimType Int8    where typeRep = Int8T
+instance PrimType Int16   where typeRep = Int16T
+instance PrimType Int32   where typeRep = Int32T
+instance PrimType Int64   where typeRep = Int64T
+instance PrimType Word8   where typeRep = Word8T
+instance PrimType Word16  where typeRep = Word16T
+instance PrimType Word32  where typeRep = Word32T
+instance PrimType Word64  where typeRep = Word64T
+instance PrimType Int     where typeRep = IntT
+instance PrimType Integer where typeRep = IntegerT
+instance PrimType Float   where typeRep = FloatT
+instance PrimType Double  where typeRep = DoubleT
+
+instance forall n . KnownNat n => PrimType (Bits n)
+  where
+    typeRep = BitsT
+
+--------------------------------------------------------------------------------
+
+-- | Print a value.
+primTypeVal :: forall a . PrimType a => a -> String
+primTypeVal a = case typeRep :: TypeRep a of
+  BoolT    -> if a then "\'1\'" else "\'0\'"
+  _        -> show a
+
+-- | Print a value as its bit representation.
+primTypeBits :: forall a . PrimType a => a -> String
+primTypeBits a = case typeRep :: TypeRep a of
+  BoolT    -> primTypeVal a
+  Int8T    -> printBits 8  a
+  Int16T   -> printBits 16 a
+  Int32T   -> printBits 32 a
+  Int64T   -> printBits 64 a
+  Word8T   -> printBits 8  a
+  Word16T  -> printBits 16 a
+  Word32T  -> printBits 32 a
+  Word64T  -> printBits 64 a
+  IntT     -> error "todo: print ints as bits."
+  IntegerT -> error "todo: print integers as bits."
+  FloatT   -> error "todo: print floats as bits."
+  DoubleT  -> error "todo: print doubles as bits."
+
+-- | Hardware type representation of a primitive type.
+primTypeRep :: forall a . PrimType a => Proxy a -> Type
+primTypeRep _ = case typeRep :: TypeRep a of
+  BoolT    -> std_logic
+  Int8T    -> signed8
+  Int16T   -> signed16
+  Int32T   -> signed32
+  Int64T   -> signed64
+  Word8T   -> usigned8
+  Word16T  -> usigned16
+  Word32T  -> usigned32
+  Word64T  -> usigned64
+  IntT     -> integer Nothing -- todo: might be wrong.
+  IntegerT -> integer Nothing -- todo: migth be wrong.
+  FloatT   -> float
+  DoubleT  -> double
+  BitsT    -> primTypeRepBits (Proxy :: Proxy a)
+
+primTypeRepBits :: forall n . KnownNat n => Proxy (Bits n) -> Type
+primTypeRepBits _ = std_logic_vector size
+  where size = fromInteger (ni (undefined :: Bits n))
+
+-- | Declare the necessary imports/packages to support a primitive type.
+primTypeDeclare :: forall a . PrimType a => Proxy a -> VHDL ()
+primTypeDeclare p = case typeRep :: TypeRep a of
+  BoolT    -> declareBoolean
+  Int8T    -> declareNumeric
+  Int16T   -> declareNumeric
+  Int32T   -> declareNumeric
+  Int64T   -> declareNumeric
+  Word8T   -> declareNumeric
+  Word16T  -> declareNumeric
+  Word32T  -> declareNumeric
+  Word64T  -> declareNumeric
+  IntT     -> declareNumeric
+  IntegerT -> declareNumeric
+  FloatT   -> declareFloating
+  DoubleT  -> declareFloating
+  BitsT    -> declareBoolean
+
+-- | Declare a primitive hardware type and get back its representation.
+declareType :: PrimType a => Proxy a -> VHDL Type
+declareType proxy = primTypeDeclare proxy >> return (primTypeRep proxy)
+
+-- | Declare the necessary libraries to support boolean operations.
+declareBoolean :: VHDL ()
+declareBoolean =
+  do newLibrary "IEEE"
+     newImport  "IEEE.std_logic_1164"
+
+-- | Declare the necessary libraries to support numerical operations.
+declareNumeric :: VHDL ()
+declareNumeric =
+  do newLibrary "IEEE"
+     newImport  "IEEE.std_logic_1164"
+     newImport  "IEEE.numeric_std"
+
+-- | Declare the necessary libraries to support floating point operations.
+declareFloating :: VHDL ()
+declareFloating =
+  do newLibrary "IEEE"
+     newImport  "IEEE.float_pkg"
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Expression/Represent/Bit.hs b/src/Language/Embedded/Hardware/Expression/Represent/Bit.hs
--- a/src/Language/Embedded/Hardware/Expression/Represent/Bit.hs
+++ b/src/Language/Embedded/Hardware/Expression/Represent/Bit.hs
@@ -38,25 +38,15 @@
   , bitToList
   , bitShowBin
   , bitShowHex
-
-  , UBits
-  , forgetBits
-  , recallBits
   )
   where
 
-import Language.Embedded.Hardware.Expression.Represent
-
-import Language.Embedded.VHDL            (VHDL)
-import Language.Embedded.VHDL.Monad      (newSym, newLibrary, newImport)
-import Language.Embedded.VHDL.Monad.Type
-
 import Data.Ix
 import Data.Typeable
 import Data.Bits hiding (Bits)
 import qualified Data.Bits as Bit (Bits)
 
-import Control.Monad   (guard)
+import Control.Monad (guard)
 import Control.DeepSeq (NFData(..))
 
 import Data.Char (intToDigit)
@@ -65,54 +55,14 @@
 import GHC.TypeLits
 
 --------------------------------------------------------------------------------
--- * ...
+-- * Bit vectors of known lenght.
 --------------------------------------------------------------------------------
 
---------------------------------------------------------------------------------
--- ** Single bit.
-
-type Bit = Bool
-
---------------------------------------------------------------------------------
--- These aren't great to have..
-
-instance Real Bool
-  where
-    toRational = error "toRational not implemented for bit."
-
-instance Integral Bool
-  where
-    toInteger True  = 1
-    toInteger False = 0
-    quotRem         = error "quotRem not implemented for bit."
-
---------------------------------------------------------------------------------
--- ** Bit vectors of known lenght.
-
 newtype Bits (n :: Nat) = B Integer
 
-instance forall n. KnownNat n => Inhabited (Bits n)
-  where
-    reset = bitFromInteger 0
-
-instance forall n. KnownNat n => Rep (Bits n)
-  where
-    declare     = declareBits
-    printVal    = show . bitToInteger
-    printBits b = '\"' : (tail $ bitShowBin b) ++ ['\"'] -- *** why tail?
-
-instance forall n. KnownNat n => Sized (Bits n)
-  where
-    bits _ = ni (Proxy::Proxy n)
-
 deriving instance Typeable (Bits n)
-
-declareBits :: forall proxy n. KnownNat n => proxy (Bits n) -> VHDL Type
-declareBits _ = declareBoolean >> return (std_logic_vector size)
-  where size = fromInteger (ni (undefined :: Bits n))
         
 --------------------------------------------------------------------------------
--- *** ...
 
 ni :: KnownNat n => proxy n -> Integer
 ni = fromIntegral . natVal
@@ -127,7 +77,6 @@
 bitToInteger (B i) = i
 
 --------------------------------------------------------------------------------
--- *** ...
 
 lift1 :: KnownNat n => (Integer -> Integer) -> Bits n -> Bits n
 lift1 f (B i) = norm (B (f i))
@@ -136,7 +85,6 @@
 lift2 f (B i) (B j) = norm (B (f i j))
 
 --------------------------------------------------------------------------------
--- *** ...
 
 bitAdd :: KnownNat n => Bits n -> Bits n -> Bits n
 bitAdd = lift2 (+)
@@ -207,7 +155,9 @@
 bitRotate :: KnownNat n => Bits n -> Int -> Bits n
 bitRotate b@(B i) n
   | si < 2    = b
-  | otherwise = bitOr (bitFromInteger (shiftL i n)) (bitFromInteger (shiftR i (si - n)))
+  | otherwise =
+      bitOr (bitFromInteger (shiftL i n))
+            (bitFromInteger (shiftR i (si - n)))
   where n' = mod n si
         si = fromInteger (ni b)
 
@@ -303,36 +253,32 @@
   inRange = undefined
 
 --------------------------------------------------------------------------------
--- ** Bit vectors of unknown lenght.
-
-newtype UBits = UB Integer
-  deriving (Eq, Enum, Ord, Num, Real, Integral)
-
-instance Rep UBits
-  where
-    declare  = declareUBits
-    printVal = show
-    -- *** This is bad and produces a warning in vhdl as there's no guarantee
-    --     that the lenght of the printed binary will be the expected one.
-    --     Give UB an extra 'Maybe Integer' for storing the length whenever its
-    --     available.
-    printBits (UB i) = '\"' : (N.showIntAtBase 2 intToDigit i "") ++ ['\"']
-    
+-- * Bit.
+--------------------------------------------------------------------------------
 
-declareUBits :: proxy UBits -> VHDL Type
-declareUBits _ = declareBoolean >> return std_logic
+type Bit = Bool
 
 --------------------------------------------------------------------------------
-
-forgetBits :: Bits n -> UBits
-forgetBits b = UB (bitToInteger b)
+-- These aren't too great to have..
 
-recallBits :: KnownNat n => UBits -> Bits n
-recallBits (UB i) = (B i)
+instance Num Bool where
+  (+)    = error "(+) not implemented for Bool"
+  (-)    = error "(-) not implemented for Bool"
+  (*)    = error "(*) not implemented for Bool"
+  abs    = id
+  signum = id
+  fromInteger 0 = False
+  fromInteger 1 = True
+  fromInteger _ = error "bool-num: >1"  
 
---------------------------------------------------------------------------------
+instance Real Bool
+  where
+    toRational = error "toRational not implemented for bit."
 
-instance Show UBits where
-  showsPrec p (UB x) = showsPrec p x
+instance Integral Bool
+  where
+    toInteger True  = 1
+    toInteger False = 0
+    quotRem         = error "quotRem not implemented for bit."
 
 --------------------------------------------------------------------------------
diff --git a/src/Language/Embedded/Hardware/Expression/Syntax.hs b/src/Language/Embedded/Hardware/Expression/Syntax.hs
--- a/src/Language/Embedded/Hardware/Expression/Syntax.hs
+++ b/src/Language/Embedded/Hardware/Expression/Syntax.hs
@@ -6,6 +6,7 @@
 {-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances  #-}
 {-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE ConstraintKinds       #-}
 
 module Language.Embedded.Hardware.Expression.Syntax where
 
@@ -14,7 +15,9 @@
 
 import qualified Language.VHDL as V (Name, Aggregate)
 
-import Language.Embedded.Hardware.Command (CompArrayIx)
+--import Language.Embedded.Hardware.Command (CompArrayIx)
+--instance CompArrayIx HExp
+
 import Language.Embedded.Hardware.Interface
 import Language.Embedded.Hardware.Expression.Represent
 import Language.Embedded.Hardware.Expression.Represent.Bit
@@ -41,7 +44,7 @@
 -- | Typed expressions.
 data T sig
   where
-    T :: HType (DenResult sig) => { unT :: Dom sig } -> T sig
+    T :: PrimType (DenResult sig) => { unT :: Dom sig } -> T sig
 
 -- | Specialized sugarSym for T.
 sugarT
@@ -49,11 +52,14 @@
      , T :<: SmartSym fi
      , SyntacticN f fi
      , SmartFun (SmartSym fi) (SmartSig fi) ~ fi
-     , HType (DenResult (SmartSig fi)))
+     , PrimType (DenResult (SmartSig fi)))
   => sub (SmartSig fi)
   -> f
 sugarT sym = sugarSym (T $ inj sym)
 
+-- | Hardware primitive types.
+type HType = PrimType
+
 -- | Hardware expressions.
 newtype HExp a = HExp { unHExp :: ASTF T a }
 
@@ -81,66 +87,65 @@
 -- | Relational expressions.
 data Relational sig
   where
-    Eq   :: (HType a)        => Relational (a :-> a :-> Full Bool)
-    Neq  :: (HType a)        => Relational (a :-> a :-> Full Bool)
-    Lt   :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)
-    Lte  :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)
-    Gt   :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)
-    Gte  :: (HType a, Ord a) => Relational (a :-> a :-> Full Bool)
+    Eq   :: (PrimType a)        => Relational (a :-> a :-> Full Bool)
+    Neq  :: (PrimType a)        => Relational (a :-> a :-> Full Bool)
+    Lt   :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)
+    Lte  :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)
+    Gt   :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)
+    Gte  :: (PrimType a, Ord a) => Relational (a :-> a :-> Full Bool)
 
 -- | Bit vector expressions.
 data ShiftExpression sig
   where
-    Sll :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
-    Srl :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
-    Sla :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
-    Sra :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
-    Rol :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
-    Ror :: (HType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Sll :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Srl :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Sla :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Sra :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Rol :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
+    Ror :: (PrimType a, B.Bits a) => ShiftExpression (a :-> Integer :-> Full a)
 
 -- | Numerical expressions.
 data SimpleExpression sig
   where
-    Neg :: (HType a, Num a) => SimpleExpression (a :->       Full a)
-    Pos :: (HType a, Num a) => SimpleExpression (a :->       Full a)
-    Add :: (HType a, Num a) => SimpleExpression (a :-> a :-> Full a)
-    Sub :: (HType a, Num a) => SimpleExpression (a :-> a :-> Full a)
+    Neg :: (PrimType a, Num a) => SimpleExpression (a :->       Full a)
+    Pos :: (PrimType a, Num a) => SimpleExpression (a :->       Full a)
+    Add :: (PrimType a, Num a) => SimpleExpression (a :-> a :-> Full a)
+    Sub :: (PrimType a, Num a) => SimpleExpression (a :-> a :-> Full a)
     Cat :: (KnownNat n, KnownNat m)
         => SimpleExpression (Bits n :-> Bits m :-> Full (Bits (n + m)))
 
 -- | Integral expressions.
 data Term sig
   where
-    Mul :: (HType a, Num a)      => Term (a :-> a :-> Full a)
-    Div :: (HType a, Integral a) => Term (a :-> a :-> Full a)
-    Mod :: (HType a, Integral a) => Term (a :-> a :-> Full a)
-    Rem :: (HType a, Integral a) => Term (a :-> a :-> Full a)
+    Mul :: (PrimType a, Num a)      => Term (a :-> a :-> Full a)
+    Div :: (PrimType a, Integral a) => Term (a :-> a :-> Full a)
+    Mod :: (PrimType a, Integral a) => Term (a :-> a :-> Full a)
+    Rem :: (PrimType a, Integral a) => Term (a :-> a :-> Full a)
 
 -- | ...
 data Factor sig
   where
-    Exp :: (HType a, Num a, HType b, Integral b) => Factor (a :-> b :-> Full a)
-    Abs :: (HType a, Num a) => Factor (a :-> Full a)
+    Exp :: (PrimType a, Num a, PrimType b, Integral b)
+        => Factor (a :-> b :-> Full a)
+    Abs :: (PrimType a, Num a) => Factor (a :-> Full a)
     Not :: Factor (Bool :-> Full Bool)
 
 -- | ...
 data Primary sig
   where
-    Name       :: (HType a) => V.Name      -> Primary (Full a)
-    Literal    :: (HType a) => a           -> Primary (Full a)
-    Aggregate  :: (HType a) => V.Aggregate -> Primary (Full a)
+    Name       :: (PrimType a) => V.Name -> Primary (Full a)
+    Literal    :: (PrimType a) => a -> Primary (Full a)
+    Aggregate  :: (PrimType a) => V.Aggregate -> Primary (Full a)
     Function   :: (Signature sig) => String -> Denotation sig -> Primary sig
-    Qualified  :: (HType a, HType b) => b        -> Primary (a :-> Full a)
-    Conversion :: (HType a, HType b) => (a -> b) -> Primary (a :-> Full b)
-    Allocator  :: (HType a) => Primary (Full a)
+    Qualified  :: (PrimType a, PrimType b) => b -> Primary (a :-> Full a)
+    Conversion :: (PrimType a, PrimType b) => (a -> b) -> Primary (a :-> Full b)
+    Allocator  :: (PrimType a) => Primary (Full a)
     -- *** todo: expanded aggregate
     Others     :: Primary (Bit :-> Full (Bits n))
     
 --------------------------------------------------------------------------------
 -- ** Syntactic instances.
 
-instance CompArrayIx HExp
-
 instance Equality T
   where
     equal (T s) (T t) = equal s t
@@ -378,3 +383,51 @@
 instance EvalEnv Primary env
 
 --------------------------------------------------------------------------------
+-- *** Temporary fix until GHC fixes their class resolution for DTC ***
+--------------------------------------------------------------------------------
+
+instance {-# OVERLAPPING #-} Project sub Dom => Project sub (AST T)
+  where
+    prj (Sym s) = prj s
+
+instance {-# OVERLAPPING #-} Project sub Dom => Project sub T
+  where
+    prj (T a) = prj a
+
+instance {-# OVERLAPPING #-} Project Expression Dom
+  where
+    prj (InjL a) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project Relational Dom
+  where
+    prj (InjR (InjL a)) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project ShiftExpression Dom
+  where
+    prj (InjR (InjR (InjL a))) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project SimpleExpression Dom
+  where
+    prj (InjR (InjR (InjR (InjL a)))) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project Term Dom
+  where
+    prj (InjR (InjR (InjR (InjR (InjL a))))) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project Factor Dom
+  where
+    prj (InjR (InjR (InjR (InjR (InjR (InjL a)))))) = Just a
+    prj _ = Nothing
+
+instance {-# OVERLAPPING #-} Project Primary Dom
+  where
+    prj ((InjR (InjR (InjR (InjR (InjR (InjR a))))))) = Just a
+    prj _ = Nothing
+
+--------------------------------------------------------------------------------
+
diff --git a/src/Language/Embedded/Hardware/Interface/AXI.hs b/src/Language/Embedded/Hardware/Interface/AXI.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Embedded/Hardware/Interface/AXI.hs
@@ -0,0 +1,644 @@
+{-# LANGUAGE ScopedTypeVariables   #-}
+{-# LANGUAGE FlexibleContexts      #-}
+{-# LANGUAGE DataKinds             #-}
+{-# LANGUAGE TypeOperators         #-}
+{-# LANGUAGE TypeFamilies          #-}
+{-# LANGUAGE ConstraintKinds       #-}
+{-# LANGUAGE PolyKinds             #-}
+{-# LANGUAGE GADTs                 #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances     #-}
+
+module Language.Embedded.Hardware.Interface.AXI (axi_light, AXIPred) where
+
+import Language.Embedded.VHDL (Mode(..))
+import Language.Embedded.Hardware.Command.CMD
+import Language.Embedded.Hardware.Command.Frontend
+import Language.Embedded.Hardware.Interface
+import Language.Embedded.Hardware.Expression.Frontend
+import Language.Embedded.Hardware.Expression.Represent
+import Language.Embedded.Hardware.Expression.Represent.Bit (Bits, Bit, bitFromInteger, ni)
+
+import Control.Monad.Identity (Identity)
+import Control.Monad.Operational.Higher hiding (when)
+import Data.Constraint (Constraint)
+import Data.Typeable
+import Data.Int
+import Data.Word
+import Data.Bits ()
+import Data.Ix (Ix)
+
+import GHC.TypeLits
+import qualified GHC.Exts as GHC (Constraint)
+
+import Prelude hiding (not, and, or, div, null)
+import qualified Prelude as P
+
+--------------------------------------------------------------------------------
+-- * AXI-light Controller.
+--------------------------------------------------------------------------------
+-- todo : we make a slight simplification and assume that components which we
+--        connect to AXI-lite has a signature of
+--          "input -> input -> .. -> input -> output -> ()"
+--        this can easily be fixed by inspecting the modes given by the
+--        signature.
+--------------------------------------------------------------------------------
+
+-- | Short-hand for programs.
+type Prog instr exp pred = Program instr (Param2 exp pred)
+
+-- | Short-hand for constraints.
+type AXIPred instr exp pred = (
+       SignalCMD      :<: instr
+     , ArrayCMD       :<: instr
+     , VariableCMD    :<: instr
+     , ConditionalCMD :<: instr
+     , StructuralCMD  :<: instr
+     , LoopCMD        :<: instr
+     , ComponentCMD   :<: instr
+     , VHDLCMD        :<: instr
+--
+     , Expr    exp
+     , Rel     exp
+     , Factor  exp
+     , Primary exp
+--
+     , FreeExp exp
+       -- todo: this equality might be bad. It should be enough to
+       --       say that 'PredicateExp' holds, and not that it has
+       --       to be equal to 'pred'.
+     , pred ~ PredicateExp exp
+     , pred (Bit)
+     , pred (Bits 2)
+     , pred (Bits 3)
+     , pred (Bits 4)
+     , pred (Bits 32)
+     , pred (Integer)
+     , Num (exp Integer)
+     )
+
+--------------------------------------------------------------------------------
+-- ** Signature.
+--------------------------------------------------------------------------------
+
+axi_light
+  :: forall instr exp pred sig . AXIPred instr exp pred
+  => Comp instr exp pred Identity sig
+  -> Sig  instr exp pred Identity (
+          Signal Bit       -- ^ Global clock signal.
+       -> Signal Bit       -- ^ Global reset signal.
+       -> Signal (Bits 32) -- ^ Write address.
+       -> Signal (Bits 3)  -- ^ Write channel protection type.
+       -> Signal Bit       -- ^ Write address valid.
+       -> Signal Bit       -- ^ Write address ready.
+       -> Signal (Bits 32) -- ^ Write data.
+       -> Signal (Bits 4)  -- ^ Write strobes.
+       -> Signal Bit       -- ^ Write valid.
+       -> Signal Bit       -- ^ Write ready.
+       -> Signal (Bits 2)  -- ^ Write response.
+       -> Signal Bit       -- ^ Write response valid.
+       -> Signal Bit       -- ^ Response ready.
+       -> Signal (Bits 32) -- ^ Read address.
+       -> Signal (Bits 3)  -- ^ Protection type.
+       -> Signal Bit       -- ^ Read address valid.
+       -> Signal Bit       -- ^ Read address ready.
+       -> Signal (Bits 32) -- ^ Read data.
+       -> Signal (Bits 2)  -- ^ Read response.
+       -> Signal Bit       -- ^ Read valid.
+       -> Signal Bit       -- ^ Read ready.    
+       -> ()
+     )
+axi_light comp =
+  exactInput  "S_AXI_ACLK"    $ \s_axi_aclk    ->       
+  exactInput  "S_AXI_ARESETN" $ \s_axi_aresetn -> 
+  exactInput  "S_AXI_AWADDR"  $ \s_axi_awaddr  ->
+  exactInput  "S_AXI_AWPROT"  $ \s_axi_awprot  ->
+  exactInput  "S_AXI_AWVALID" $ \s_axi_awvalid -> 
+  exactOutput "S_AXI_AWREADY" $ \s_axi_awready ->
+  exactInput  "S_AXI_WDATA"   $ \s_axi_wdata   ->
+  exactInput  "S_AXI_WSTRB"   $ \s_axi_wstrb   ->
+  exactInput  "S_AXI_WVALID"  $ \s_axi_wvalid  ->   
+  exactOutput "S_AXI_WREADY"  $ \s_axi_wready  ->   
+  exactOutput "S_AXI_BRESP"   $ \s_axi_bresp   ->     
+  exactOutput "S_AXI_BVALID"  $ \s_axi_bvalid  ->   
+  exactInput  "S_AXI_BREADY"  $ \s_axi_bready  ->   
+  exactInput  "S_AXI_ARADDR"  $ \s_axi_araddr  ->
+  exactInput  "S_AXI_ARPROT"  $ \s_axi_arprot  ->
+  exactInput  "S_AXI_ARVALID" $ \s_axi_arvalid ->   
+  exactOutput "S_AXI_ARREADY" $ \s_axi_arready ->
+  exactOutput "S_AXI_RDATA"   $ \s_axi_rdata   ->     
+  exactOutput "S_AXI_RRESP"   $ \s_axi_rresp   ->     
+  exactOutput "S_AXI_RVALID"  $ \s_axi_rvalid  ->
+  exactInput  "S_AXI_RREADY"  $ \s_axi_rready  ->   
+  ret $ axi_light_impl comp
+    s_axi_aclk s_axi_aresetn
+    s_axi_awaddr s_axi_awprot s_axi_awvalid s_axi_awready
+    s_axi_wdata  s_axi_wstrb  s_axi_wvalid  s_axi_wready
+    s_axi_bresp  s_axi_bvalid s_axi_bready
+    s_axi_araddr s_axi_arprot s_axi_arvalid s_axi_arready s_axi_rdata
+    s_axi_rresp  s_axi_rvalid s_axi_rready     
+
+--------------------------------------------------------------------------------
+-- ** Implementation.
+--------------------------------------------------------------------------------
+
+axi_light_impl
+  :: forall instr exp pred sig . AXIPred instr exp pred
+  -- Component to connect:
+  => Comp instr exp pred Identity sig
+  -- AXI signals:
+  -> Signal Bit       -- ^ Global clock signal.
+  -> Signal Bit       -- ^ Global reset signal.
+  -> Signal (Bits 32) -- ^ Write address.
+  -> Signal (Bits 3)  -- ^ Write channel protection type.
+  -> Signal Bit       -- ^ Write address valid.
+  -> Signal Bit       -- ^ Write address ready.
+  -> Signal (Bits 32) -- ^ Write data.
+  -> Signal (Bits 4)  -- ^ Write strobes.
+  -> Signal Bit       -- ^ Write valid.
+  -> Signal Bit       -- ^ Write ready.
+  -> Signal (Bits 2)  -- ^ Write response.
+  -> Signal Bit       -- ^ Write response valid.
+  -> Signal Bit       -- ^ Response ready.
+  -> Signal (Bits 32) -- ^ Read address.
+  -> Signal (Bits 3)  -- ^ Protection type.
+  -> Signal Bit       -- ^ Read address valid.
+  -> Signal Bit       -- ^ Read address ready.
+  -> Signal (Bits 32) -- ^ Read data.
+  -> Signal (Bits 2)  -- ^ Read response.
+  -> Signal Bit       -- ^ Read valid.
+  -> Signal Bit       -- ^ Read ready.    
+  -> Prog instr exp pred ()
+axi_light_impl comp
+    s_axi_aclk   s_axi_aresetn
+    s_axi_awaddr s_axi_awprot s_axi_awvalid s_axi_awready
+    s_axi_wdata  s_axi_wstrb  s_axi_wvalid  s_axi_wready
+    s_axi_bresp  s_axi_bvalid s_axi_bready
+    s_axi_araddr s_axi_arprot s_axi_arvalid s_axi_arready s_axi_rdata
+    s_axi_rresp  s_axi_rvalid s_axi_rready
+  = do
+       ----------------------------------------
+       -- AXI Light signals.
+       --
+       awaddr  <- signal "axi_awaddr"  :: Prog instr exp pred (Signal (Bits 32))
+       awready <- signal "axi_awready" :: Prog instr exp pred (Signal (Bit))
+       wready  <- signal "axi_wready"  :: Prog instr exp pred (Signal (Bit))
+       bresp   <- signal "axi_bresp"   :: Prog instr exp pred (Signal (Bits 2))
+       bvalid  <- signal "axi_bvalid"  :: Prog instr exp pred (Signal (Bit))
+       araddr  <- signal "axi_araddr"  :: Prog instr exp pred (Signal (Bits 32))
+       arready <- signal "axi_arready" :: Prog instr exp pred (Signal (Bit))
+       rdata   <- signal "axi_rdata"   :: Prog instr exp pred (Signal (Bits 32))
+       rresp   <- signal "axi_rresp"   :: Prog instr exp pred (Signal (Bits 2))
+       rvalid  <- signal "axi_rvalid"  :: Prog instr exp pred (Signal (Bit))
+
+       ----------------------------------------
+       -- Signals for user logic registers.
+       --
+       reg_rden  <- signal "slv_reg_rden" :: Prog instr exp pred (Signal (Bit))
+       reg_wren  <- signal "slv_reg_wren" :: Prog instr exp pred (Signal (Bit))
+       reg_out   <- signal "reg_data_out" :: Prog instr exp pred (Signal (Bits 32))
+       reg_index <- signal "byte_index"   :: Prog instr exp pred (Signal (Integer))
+       registers <- declareRegisters (signatureOf comp)
+
+       ----------------------------------------
+       -- Short-hands for ...
+       --
+       -- > reset all input registers.
+       let mReset  = resetInputs  (signatureOf comp) registers
+       -- > reload all input registers.
+       let mReload = reloadInputs (signatureOf comp) registers
+       -- > fetch the names of all input registers.
+       let mInputs = identInputs  (signatureOf comp) registers
+       -- > write to output.
+       let mWrite :: Prog instr exp pred ()
+           mWrite = loadOutputs araddr reg_out
+             (signatureOf comp)
+             (registers)
+       -- > read from input.
+       let mRead :: Prog instr exp pred ()
+           mRead = loadInputs awaddr reg_wren s_axi_wdata s_axi_wstrb
+             (signatureOf comp)
+             (registers)
+       
+       ----------------------------------------
+       -- I/O Connections.
+       --
+       s_axi_awready <=- awready
+       s_axi_wready  <=- wready
+       s_axi_bresp   <=- bresp
+       s_axi_bvalid  <=- bvalid
+       s_axi_arready <=- arready
+       s_axi_rdata   <=- rdata
+       s_axi_rresp   <=- rresp
+       s_axi_rvalid  <=- rvalid
+
+       ----------------------------------------
+       -- Mem. mapped register select and write
+       -- logic generation.
+       --
+       u_wr  <- unsafeFreezeSignal wready
+       u_wv  <- unsafeFreezeSignal s_axi_wvalid
+       u_awr <- unsafeFreezeSignal awready
+       u_awv <- unsafeFreezeSignal s_axi_awvalid
+       concurrentSetSignal reg_wren
+         (u_wr `and` u_wv `and` u_awr `and` u_awv)
+
+       ----------------------------------------
+       -- Mem. mapped register select and read
+       -- logic generation.
+       --
+       u_arr <- unsafeFreezeSignal arready
+       u_arv <- unsafeFreezeSignal s_axi_arvalid
+       u_rv  <- unsafeFreezeSignal rvalid
+       concurrentSetSignal reg_rden
+         (u_arr `and` u_arv `and` not u_rv)
+
+       ----------------------------------------
+       -- AXI_AWREADY generation.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do awready <== low)
+           (do rdy <- getSignal awready
+               awv <- getSignal s_axi_awvalid
+               wv  <- getSignal s_axi_wvalid
+               iff (isLow rdy `and` isHigh awv `and` isHigh wv)
+                 (do awready <== high)
+                 (do awready <== low)))
+           
+       ----------------------------------------
+       -- AXI_AWADDR latching.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do awaddr <== zeroes)
+           (do rdy <- getSignal awready
+               awv <- getSignal s_axi_awvalid
+               wv  <- getSignal s_axi_wvalid
+               when (isLow  rdy `and` isHigh awv `and` isHigh wv)
+                 (awaddr <=- s_axi_awaddr)))
+
+       ----------------------------------------
+       -- AXI_WREADY generation.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do wready <== low)
+           (do rdy <- getSignal awready
+               awv <- getSignal s_axi_awvalid
+               wv  <- getSignal s_axi_wvalid
+               iff (isLow  rdy `and` isHigh awv `and` isHigh wv)
+                 (wready <== high)
+                 (wready <== low)))
+
+       ----------------------------------------
+       -- Slave register logic.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           mReset
+           mRead)
+       
+       ----------------------------------------
+       -- Write response logic.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do bvalid <== low
+               bresp  <== zeroes)
+           (do awr <- getSignal awready
+               awv <- getSignal s_axi_awvalid
+               wr  <- getSignal wready
+               wv  <- getSignal s_axi_wvalid
+               bv  <- getSignal bvalid
+               br  <- getSignal s_axi_bready
+               ifE ((isHigh awr `and` isHigh awv
+                                `and` isHigh wr
+                                `and` isHigh wv
+                                `and` isLow bv),
+                     do bvalid <== high
+                        bresp  <== zeroes)
+                   ((isHigh br  `and` isHigh bv),
+                     do bvalid <== low)))
+
+       ----------------------------------------
+       -- AXI_AWREADY generation.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do arready <== low
+               araddr  <== ones)
+           (do arr <- getSignal arready
+               arv <- getSignal s_axi_arvalid
+               iff (isLow arr `and` isHigh arv)
+                 (do arready <== high
+                     araddr  <=- s_axi_araddr)
+                 (do arready <== low)))
+
+       ----------------------------------------
+       -- AXI_ARVALID generation.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do rvalid <== low
+               rresp  <== zeroes)
+           (do arr <- getSignal arready
+               arv <- getSignal s_axi_arvalid
+               rv  <- getSignal rvalid
+               rr  <- getSignal s_axi_rready
+               ifE ((isHigh arr `and` isHigh arv),
+                     do rvalid <== high
+                        rresp  <== zeroes)
+                   ((isHigh rv  `and` isHigh rr),
+                     do rvalid <== low)))
+
+       ----------------------------------------
+       -- Memory mapped rigister select and
+       -- read logic generaiton.
+       --
+       process (araddr .: s_axi_aresetn .: reg_rden .: mInputs) (do
+         mWrite)
+
+       ----------------------------------------
+       -- Output register of memory read data.
+       --
+       process (s_axi_aclk .: []) (do
+         whenRising s_axi_aclk s_axi_aresetn
+           (do rdata <== zeroes)
+           (do rden <- getSignal reg_rden
+               when (isHigh rden)
+                 (do rdata <=- reg_out)))
+
+       ----------------------------------------
+       -- User logic.
+       --
+       portmap comp registers
+       --
+       -- The end.
+       ----------------------------------------
+  where
+    -- Application-specific design signals.
+    addr_lsb, addr_bits :: Integer
+    addr_lsb  = 2
+    addr_bits = 2 + 1
+      --addr_lsb + (widthOf comp)
+
+--------------------------------------------------------------------------------
+-- ** Helpers.
+--------------------------------------------------------------------------------
+
+-- | Declare the registers which will be used by our AXI-lite slave to store
+--   values received from the master and, once filled, as input for the comp.
+declareRegisters :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred
+  => Sig  instr exp pred Identity a
+  -> Prog instr exp pred (Argument pred a)
+declareRegisters (Ret _) = return Nil
+declareRegisters (SSig _ _ sf) =
+  do s <- newSignal
+     a <- declareRegisters (sf s)
+     return (ASig s a)
+declareRegisters (SArr _ _ l af) =
+  do s <- newArray (litE l)
+     a <- declareRegisters (af s)
+     return (AArr s a)
+
+--------------------------------------------------------------------------------
+
+-- | Reset the input registers.
+resetInputs :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred
+  => Sig  instr exp pred Identity a
+  -> Argument pred a
+  -> Prog instr exp pred ()
+resetInputs (Ret _)           (Nil)        = return ()
+resetInputs (SSig _ Out   sf) (ASig s arg) = resetInputs (sf s) arg
+resetInputs (SArr _ Out _ af) (AArr a arg) = resetInputs (af a) arg
+resetInputs (SSig _ In    sf) (ASig s arg) =
+  do setSignal s (litE reset)
+     resetInputs (sf s) arg
+resetInputs (SArr _ In  _ af) (AArr a arg) =
+  do resetArray a (litE reset)
+     resetInputs (af a) arg
+
+--------------------------------------------------------------------------------
+
+-- | Reset the input registers to their previous values.
+reloadInputs :: forall instr (exp :: * -> *) pred m a . AXIPred instr exp pred
+  => Sig  instr exp pred Identity a
+  -> Argument pred a
+  -> Prog instr exp pred ()
+reloadInputs (Ret _)           (Nil)        = return ()
+reloadInputs (SSig _ Out   sf) (ASig s arg) = reloadInputs (sf s) arg
+reloadInputs (SArr _ Out _ af) (AArr a arg) = reloadInputs (af a) arg
+reloadInputs (SSig _ In    sf) (ASig s arg) =
+  do sv <- unsafeFreezeSignal s
+     setSignal s sv
+     reloadInputs (sf s) arg
+reloadInputs (SArr _ In  l af) (AArr a arg) =
+  do copyArray (a, litE 0) (a, litE 0) (litE l)
+     reloadInputs (af a) arg
+
+--------------------------------------------------------------------------------
+
+-- | ...
+loadInputs :: forall instr (exp :: * -> *) pred a . AXIPred instr exp pred
+  => Signal   (Bits 32) -- ^ Address.
+  -> Signal   (Bit)     -- ^ Ready.
+  -> Signal   (Bits 32) -- ^ Input.
+  -> Signal   (Bits 4)  -- ^ Protected bits.
+  -> Sig instr exp pred Identity a
+  -> Argument pred a
+  -> Prog instr exp pred ()
+loadInputs waddr rwren wdata wren sig arg =
+  do loc   <- getBits waddr addr_lsb addr_msb
+     ready <- getSignal rwren
+     when (isHigh ready) $
+       switched loc
+         (cases 0 sig arg)
+         (reloadInputs sig arg)
+  where
+    cases :: Integer
+          -> Sig instr exp pred Identity b
+          -> Argument pred b
+          -> [When Integer (Prog instr exp pred)]
+    cases ix (Ret _)         (Nil)        = []
+    cases ix (SArr _ _ l af) (AArr a arg) = error "axi-todo: loading arrays."
+    cases ix (SSig _ Out sf) (ASig s arg) = cases (ix+1) (sf s) arg
+    cases ix (SSig _ In  sf) (ASig s arg) =
+      is (ix) (loadInputSignal wdata wren s) : cases (ix+1) (sf s) arg
+
+    addr_lsb, addr_msb :: exp Integer
+    addr_lsb = litE 2
+    addr_msb = litE 3
+
+loadInputSignal :: forall instr (exp :: * -> *) pred a .
+     (AXIPred instr exp pred, pred a, Sized a)
+  => Signal (Bits 32)
+  -> Signal (Bits 4)
+  -> Signal a
+  -> Prog instr exp pred ()
+loadInputSignal wdata wren reg = for 0 size $ \byte_index ->
+  do bit <- getBit wren byte_index
+     when (isHigh bit) $
+       copyBits (reg, byte_index*8) (wdata, byte_index*8) (litE 7)
+  where
+    size :: exp Integer
+    size = litE $ (P.div (bits reg) 8) - 1
+-- todo: I assume that `a` has a type \width\ that is some multiple of eight,
+--       hence the hard-coded seven when copying.
+
+--------------------------------------------------------------------------------
+
+-- | ...
+loadOutputs :: forall instr (exp :: * -> *) pred a . AXIPred instr exp pred
+  => Signal (Bits 32) -- ^ Address.
+  -> Signal (Bits 32) -- ^ Output.
+  -> Sig instr exp pred Identity a
+  -> Argument pred a
+  -> Prog instr exp pred ()
+loadOutputs araddr rout sig arg =
+  do loc <- getBits araddr addr_lsb addr_msb
+     switched loc
+       (cases 0 sig arg)
+       (setSignal rout (litE reset))
+  where
+    cases :: Integer
+          -> Sig instr exp pred Identity b
+          -> Argument pred b
+          -> [When Integer (Prog instr exp pred)]
+    cases ix (Ret _) (Nil) = []
+    cases ix (SArr _ _ l af) (AArr a arg) = error "axi-todo: loading arrays."
+    cases ix (SSig _ Out sf) (ASig s arg) = cases (ix+1) (sf s) arg
+    cases ix (SSig _ In  sf) (ASig s arg) =
+      is (ix) (loadOutputSignal rout s) : cases (ix+1) (sf s) arg
+
+    addr_lsb, addr_msb :: exp Integer
+    addr_lsb = litE 2
+    addr_msb = litE 3
+
+loadOutputSignal :: forall instr (exp :: * -> *) pred a .
+     (AXIPred instr exp pred, pred a, PrimType a, Integral a)
+  => Signal (Bits 32)
+  -> Signal a
+  -> Prog instr exp pred ()
+loadOutputSignal rout reg =
+  do r <- unsafeFreezeSignal reg
+     setSignal rout (toBits r :: exp (Bits 32))
+
+--------------------------------------------------------------------------------
+
+identInputs :: forall instr (exp :: * -> *) pred m a .
+     Sig instr exp pred m a
+  -> Argument pred a
+  -> [Ident]
+identInputs (Ret _) (Nil) = []
+identInputs (SSig _ In sf)   (ASig s arg) = toIdent s : identInputs (sf s) arg
+identInputs (SSig _ _  sf)   (ASig s arg) = identInputs (sf s) arg
+identInputs (SArr _ In _ af) (AArr a arg) = toIdent a : identInputs (af a) arg
+identInputs (SArr _ _  _ af) (AArr a arg) = identInputs (af a) arg
+
+--------------------------------------------------------------------------------
+
+signatureOf :: Comp instr exp pred m a -> Sig instr exp pred m a
+signatureOf (Component _ sig) = sig
+
+widthOf :: Comp instr exp pred m a -> Integer
+widthOf = go . signatureOf
+  where
+    go :: Sig instr exp pred m b -> Integer
+    go (Ret _)        = 0
+    go (SSig _ _ f)   = 1 + go (f dummy)
+--  go (SArr _ _ l g) = l + go (g dummy)
+
+dummy :: a
+dummy = error "todo: evaluated dummy"
+
+high, low :: Expr exp => exp Bit
+high = true
+low  = false
+
+isHigh, isLow :: (Expr exp, Rel exp) => exp Bit -> exp Bit
+isHigh e = e `eq` high
+isLow  e = e `eq` low
+
+zeroes :: (Primary exp, Typeable n, KnownNat n) => exp (Bits n)
+zeroes = value 0
+
+ones :: forall exp n. (Primary exp, Typeable n, KnownNat n) => exp (Bits n)
+ones = value $ bitFromInteger (read (replicate size '1') :: Integer)
+  where size = fromIntegral (ni (Proxy::Proxy n)) - 1
+
+--------------------------------------------------------------------------------
+-- Program stubs.
+--------------------------------------------------------------------------------
+{-
+loadInputs wdata wren tmp i (SSig _ In sf) (ASig s arg) =
+    When (Is i) cases : loadInputs wdata wren tmp (i+1) (sf s) arg
+  where
+    size :: Integer
+    size = bits s
+
+    loadBit :: Prog instr exp pred ()
+    loadBit = do
+      wb <- getBit wren (0 :: exp Integer)
+      undefined
+      when (isHigh wb) $
+        do bit <- getBit wdata (0 :: exp Integer)
+           setBit s (0 :: exp Integer) bit
+
+    loadBits :: Integer -> Integer -> Prog instr exp pred ()
+    loadBits ix len = do
+      wb <- getBit wren (value ix)
+      undefined
+      when (isHigh wb) $
+        copyBits (s, value $ ix*8) (wdata, value $ ix*8) (value $ len-1)
+
+    cases :: Prog instr exp pred ()
+    cases | size == 1 = loadBit
+          | otherwise = sequence_ $ map (uncurry loadBits) $ zip [0..] $ chunk size
+loadInputs wdata wren tmp i (SArr _ Out l af) (AArr a arg) =
+    loadInputs wdata wren tmp (i+(Prelude.toInteger l)) (af a) arg
+loadInputs wdata wren tmp i (SArr _ In l af) (AArr (a :: Array i b) arg)
+    let cs = map (\ix -> When (Is $ i+ix) $ cases ix) [0..l'-1]
+     in cs ++ loadInputs wdata wren tmp (i+l') (af a) arg
+  where
+    l', size :: Integer
+    l'   = Prelude.toInteger l    
+    size = bits a
+
+    loadBit :: Integer -> Prog instr exp pred ()
+    loadBit ax = error "axi-todo: loadBit for array."
+
+    loadBits :: Integer -> Integer -> Integer -> Prog instr exp pred ()
+    loadBits ax ix len = do
+      wb <- getBit wren (value ix)
+      when (isHigh wb) $
+        copyVBits (tmp, value $ ix*8) (wdata, value $ ix*8) (value $ len-1)
+
+    cases :: Integer -> Prog instr exp pred ()
+    cases ax | size == 1 = loadBit ax
+             | otherwise = do
+      sequence_ $ map (uncurry $ loadBits ax) $ zip [0..] $ chunk size
+      val :: exp (Bits 32) <- unsafeFreezeVariable tmp
+      let ix = litE (fromInteger ax) :: exp i
+      let b  = fromBits val          :: exp b
+      undefined --setArray a ix b
+-}
+{-
+loadOutputs o i (Ret _) (Nil) = []
+loadOutputs o i (SSig _ Out sf) (ASig s arg) =
+  let p = setSignal o . toBits =<< unsafeFreezeSignal s
+   in When (Is i) p : loadOutputs o (i+1) (sf s) arg
+loadOutputs o i (SSig _ _ sf) (ASig s arg) =
+  loadOutputs o (i+1) (sf s) arg
+loadOutputs o i (SArr _ Out l af) (AArr a arg) =
+  let f ix = When (Is ix) (setSignal o . toBits =<< getArray a (value ix))
+   in map f [i..i+l-1] ++ loadOutputs o (i+l) (af a) arg
+loadOutputs o i (SArr _ _ l af) (AArr a arg) =
+  loadOutputs o (i+l) (af a) arg
+
+chunk :: Integer -> [Integer]
+chunk i | i >  8 = 8 : chunk (i - 8)
+        | i <= 8 = [i]
+-}
+--------------------------------------------------------------------------------
+
diff --git a/src/Language/Embedded/VHDL/Monad/Type.hs b/src/Language/Embedded/VHDL/Monad/Type.hs
--- a/src/Language/Embedded/VHDL/Monad/Type.hs
+++ b/src/Language/Embedded/VHDL/Monad/Type.hs
@@ -9,7 +9,7 @@
   , unconstrainedArray, constrainedArray
   -- utility.
   , typeName, typeRange, typeWidth
-  , isBit, isBits, isSigned, isUnsigned, isInteger
+  , isBit, isBits, isSigned, isUnsigned, isInteger, isFloating
   ) where
 
 import Language.VHDL
@@ -159,5 +159,8 @@
 
 isInteger :: Type -> Bool
 isInteger t = "integer" == typeName t
+
+isFloating :: Type -> Bool
+isFloating t = "float" == typeName t
 
 --------------------------------------------------------------------------------
