diff --git a/CLasH/HardwareTypes.hs b/CLasH/HardwareTypes.hs
--- a/CLasH/HardwareTypes.hs
+++ b/CLasH/HardwareTypes.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-}
+{-# LANGUAGE TemplateHaskell, DeriveDataTypeable, RecordWildCards #-}
 
 module CLasH.HardwareTypes
   ( module Types
@@ -22,9 +22,27 @@
   , RAM
   , MemState
   , blockRAM
-  , Stat
+  , Clock(..)
+  , pulseLength
+  , Comp
   , simulate
   , (^^^)
+  , comp
+  , bv2u
+  , u2bv
+  , s2bv
+  , bv2s
+  , SimulatorSession
+  , SimulationState
+  , simulateM
+  , run
+  , runWithClock
+  , setInput
+  , setAndRun
+  , getOutput
+  , showOutput
+  , assert
+  , report
   ) where
 
 import Types
@@ -34,6 +52,7 @@
 import Data.Param.Signed
 import Data.Param.Unsigned 
 import Data.Bits hiding (shiftL,shiftR)
+import qualified Data.Bits as B
 
 import Language.Haskell.TH.Lift
 import Data.Typeable
@@ -43,7 +62,15 @@
 import Control.Monad.Fix (mfix)
 import qualified Prelude as P
 import Prelude hiding (id, (.))
+import qualified Data.Set as Set
 
+import qualified Data.List as L
+
+import qualified Control.Monad.Trans.State.Strict as State
+import qualified Data.Accessor.Template
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
+import qualified Control.Monad.Trans.Class as Trans
+
 import CLasH.Translator.Annotations
 
 newtype State s = State s deriving (P.Show)
@@ -93,38 +120,173 @@
             else
               mem
 
+-- ==============================
+-- = Integer/Vector Conversions =
+-- ==============================
+-- ===============
+-- = Conversions =
+-- ===============
+bv2u :: NaturalT nT => Vector nT Bit -> Unsigned nT
+bv2u bv = vfoldl (\a b -> let
+                      a' = B.shiftL a 1
+                    in
+                      if b == High then
+                        a' + 1
+                      else
+                        a'
+                 ) 0 bv
+
+bv2s :: NaturalT nT => Vector nT Bit -> Signed nT
+bv2s bv = vfoldl (\a b -> let
+                        a' = B.shiftL a 1
+                      in
+                        if b == High then
+                          a' + 1
+                        else
+                          a'
+                   ) 0 bv
+
+u2bv :: NaturalT nT => Unsigned nT -> Vector nT Bit
+u2bv u = vreverse . (vmap fst) . (vgenerate f) $ (Low,(0,u))
+  where
+    f (_,(n,u)) = if testBit u n then (High,(n+1,u)) else (Low,(n+1,u))
+    
+s2bv :: NaturalT nT => Signed nT -> Vector nT Bit
+s2bv u = vreverse . (vmap fst) . (vgenerate f) $ (Low,(0,u))
+  where
+    f (_,(n,u)) = if testBit u n then (High,(n+1,u)) else (Low,(n+1,u))
+
+-- ==========
+-- = Clocks =
+-- ==========
+data Clock = ClockUp Int | ClockDown Int
+  deriving (Eq,Ord,Show)
+
+pulseLength (ClockUp   i) = i
+pulseLength (ClockDown i) = i
+
 -- ==================
 -- = Automata Arrow =
 -- ==================
-newtype Stat i o = A {
-     apply :: i -> (o, Stat i o)
-}
+data Comp i o = C {
+    domain :: Set.Set Clock  
+  , exec   :: Clock -> i -> (o, Comp i o)
+  }
 
-instance Category Stat where
-   (A g) . (A f) = A (\b ->  let (c,f') = f b
-                                 (d,g') = g c
-                             in (d, g'.f'))
-   id = arr id
+instance Category Comp where
+  k@(C { domain = cdA, exec = g}) . (C {domain = cdB, exec = f}) =
+     C { domain = Set.union cdA cdB
+       , exec   = \clk b -> let (c,f') = f clk b
+                                (d,g') = g clk c
+                            in (d, g'.f')
+       }
+  id = arr id
 
-instance Arrow Stat where
-   arr f = A (\b -> (f b, arr f))
-   first (A f) = A (\(b,d) -> let (c,f') = f b
-                              in ((c,d), first f'))
-instance ArrowLoop Stat where
-   loop (A f) = A (\i -> let ((c,d), f') = f (i, d)
-                         in (c, loop f'))
+instance Arrow Comp where
+  arr f    = C { domain = Set.empty
+               , exec   = \clk b -> (f b, arr f)
+               }
+  first af = af { exec  = \clk (b,d) -> let (c,f') = (exec af) clk b
+                                        in ((c,d), first f')
+                }
+instance ArrowLoop Comp where
+   loop af = af { exec = (\clk i -> let ((c,d), f') = (exec af) clk (i, d)
+                                    in (c, loop f'))
+                }
 
-liftS :: s -> (State s -> i -> (State s,o)) -> Stat i o
-liftS init f = A applyS
-   where applyS = \i -> let (State s,o) = f (State init) i
-                        in (o, liftS s f)
+comp :: (State s -> i -> (State s,o)) -> s -> Clock -> Comp i o
+comp f initS clk = C { domain = Set.singleton clk
+                     , exec = \clk' i -> let (State s,o)      = f (State initS) i
+                                             s' | clk == clk' = s
+                                                | otherwise   = initS
+                                         in (o, comp f s' clk)                                              
+                     }
 
-simulate :: Stat b c -> [b] -> [c]
-simulate (A f) []     = []
-simulate (A f) (b:bs) = let (c,f') = f b in (c : simulate f' bs)
+liftS :: s -> (State s -> i -> (State s,o)) -> Comp i o
+liftS init f = C {domain = Set.singleton (ClockUp 1), exec = applyS}
+   where applyS = \clk i -> let (State s,o) = f (State init) i
+                            in (o, liftS s f)
 
-arrState :: s -> (State s -> i -> (State s,o)) -> Stat i o
-arrState = liftS
+(^^^) :: (State s -> i -> (State s,o)) -> s -> Comp i o
+(^^^) f init = liftS init f
 
-(^^^) :: (State s -> i -> (State s,o)) -> s -> Stat i o
-(^^^) f init = arrState init f
+simulate :: Comp b c -> [b] -> [c]
+simulate af inps = if (Set.size $ domain af) < 2 then
+    simulate' af (Set.findMin $ domain af) inps
+  else
+    error "Use simulateM for components with more than 1 clock"
+
+simulate' :: Comp b c -> Clock -> [b] -> [c]
+simulate' af             _   []     = []
+simulate' (C {exec = f}) clk (i:is) = let (o,f') = f clk i in (o : simulate' f' clk is)
+
+data SimulationState i o = SimulationState {
+    clockTicks_ :: ([Clock],[Int])
+  , input_      :: i
+  , hw_         :: Comp i o
+  }
+  
+Data.Accessor.Template.deriveAccessors ''SimulationState
+
+type SimulatorSession i o a = State.StateT (SimulationState i o) IO a
+
+simulateM :: Comp i o -> SimulatorSession i o () -> IO ()
+simulateM hw testbench = State.evalStateT testbench initSession
+  where
+    initSession = SimulationState ((Set.toList $ domain hw), (replicate (Set.size $ domain hw) 1)) (error "CLasH.simulateM: initial simulation input not set") hw
+
+
+run :: Int -> SimulatorSession i o ()
+run n = do
+  (clocks,ticks) <- MonadState.get clockTicks
+  let (pulses,newTicks) = runClocks (clocks,ticks) n
+  MonadState.modify clockTicks (\(a,b) -> (a,newTicks))
+  curInp <- MonadState.get input
+  MonadState.modify hw (snd . (run' pulses curInp))
+
+runWithClock :: Clock -> Int -> SimulatorSession i o ()
+runWithClock clk n = do
+  curInp <- MonadState.get input
+  MonadState.modify hw (snd . (run' (replicate n clk) curInp))
+  
+run' []         _ arch     = ([],arch)
+run' (clk:clks) i (C {..}) = let (c,f')   = clk `seq` exec clk i
+                                 (cs,f'') = f' `seq` run' clks i f'
+                             in f'' `seq` (c:cs,f'')
+
+setInput :: i -> SimulatorSession i o ()
+setInput i = MonadState.set input i
+
+setAndRun :: i -> Int -> SimulatorSession i o ()
+setAndRun inp n = (setInput inp) >> (run n)
+
+getOutput :: SimulatorSession i o o
+getOutput = do
+  curInp <- MonadState.get input
+  arch <- MonadState.get hw
+  return $ head $ fst $ run' [ClockUp (-1)] curInp arch
+
+showOutput :: (Show o) => SimulatorSession i o ()
+showOutput = do
+  outp <- getOutput
+  Trans.lift $ putStrLn $ show outp
+  
+assert :: (o -> Bool) -> String -> SimulatorSession i o ()
+assert test msg = do
+  outp <- getOutput
+  if (test outp) then return () else Trans.lift $ putStrLn msg
+
+report :: String -> SimulatorSession i o ()
+report msg = Trans.lift $ putStrLn msg
+
+runClocks :: ([Clock], [Int]) -> Int -> ([Clock],[Int])
+runClocks (clocks, ticks) 0     = ([],ticks)
+runClocks (clocks, ticks) delta = ((concat curClocks) ++ nextClocks,nextTicks)
+  where
+    (curClocks,curTicks)   = unzip $ zipWith clockTick clocks ticks
+    (nextClocks,nextTicks) = runClocks (clocks,curTicks) (delta-1)
+
+clockTick (ClockUp   i) i' = if i == i' then ([ClockUp i]  ,1) else ([],i'+1)
+clockTick (ClockDown i) i' = if i == i' then ([ClockDown i],1) else ([],i'+1)
+
+
diff --git a/CLasH/Normalize.hs b/CLasH/Normalize.hs
--- a/CLasH/Normalize.hs
+++ b/CLasH/Normalize.hs
@@ -12,7 +12,7 @@
 import qualified Control.Monad.Trans.Class as Trans
 import qualified Control.Monad as Monad
 import qualified Control.Monad.Trans.Writer as Writer
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 import qualified Data.Monoid as Monoid
 import qualified Data.Map as Map
 
@@ -171,13 +171,15 @@
         -- initial state with this clone. We also need to replace the
         -- original reference with a reference to this clone
         initSmap <- Trans.lift $ MonadState.get tsInitStates
-        case (CoreSyn.collectArgs body, Map.lookup f initSmap) of
-          ((Var inlineF, inlineFargs), Just initState) -> do
+        clocksMap <- Trans.lift $ MonadState.get tsClocks
+        case (CoreSyn.collectArgs body, Map.lookup f initSmap, Map.lookup f clocksMap) of
+          ((Var inlineF, inlineFargs), Just initState, Just clock) -> do
             -- Get the body belong to the applied function and clone it
             inlineFbody <- Trans.lift $ getGlobalBind inlineF
             newInlineF <- Trans.lift $ mkFunction inlineF (Maybe.fromJust inlineFbody)
-            -- Associate the initial state with the cloned function
+            -- Associate the initial state and clock with the cloned function
             Trans.lift $ MonadState.modify tsInitStates (\ismap -> Map.insert (newInlineF) initState ismap)
+            Trans.lift $ MonadState.modify tsClocks (\clocksMap -> Map.insert (newInlineF) clock clocksMap)
             -- Replace original reference with a reference to the cloned function
             let newBody = mkApps (Var newInlineF) inlineFargs
             newBodyUniqued <- Trans.lift $ genUniques newBody
@@ -694,13 +696,22 @@
           let newbody = MkCore.mkCoreLams newparams (MkCore.mkCoreApps body oldargs)
           -- Create a new function with the same name but a new body
           newf <- Trans.lift $ mkFunction f newbody
+          -- Copy initial statee if it has one
           Trans.lift $ MonadState.modify tsInitStates (\ismap ->
             let 
                 init_state_maybe = Map.lookup f ismap 
             in
               case init_state_maybe of
                 Nothing -> ismap
-                Just init_state -> Map.insert (newf) init_state ismap)
+                Just init_state -> Map.insert newf init_state ismap)
+          -- Copy clock if it has one
+          Trans.lift $ MonadState.modify tsClocks (\clockMap ->
+            let 
+                clockMaybe = Map.lookup f clockMap 
+            in
+              case clockMaybe of
+                Nothing -> clockMap
+                Just clock -> Map.insert newf clock clockMap)
           -- Replace the original application with one of the new function to the
           -- new arguments.
           change $ MkCore.mkCoreApps (Var newf) newargs
@@ -1037,10 +1048,11 @@
 -- To: 
 -- \(s::s) (i::a) -> f i 
 arrowLiftSExtract :: Transform
-arrowLiftSExtract c expr@(App _ _) | isLift (appliedF, alreadyMappedArgs) = do
+arrowLiftSExtract c expr@(App _ _) | isLift (appliedF, alreadyMappedArgs) || isComponent (appliedF, alreadyMappedArgs) = do
       -- Collect the lifted function and the initial state
       let (Var liftS) = appliedF
-      let [realfun, initvalue] = get_val_args (Var.varType liftS) alreadyMappedArgs
+      let valArgs = get_val_args (Var.varType liftS) alreadyMappedArgs
+      let [realfun, initvalue] = take 2 valArgs
       -- TODO: All of this looks/is hacked! Needs rethinking and rewriting
       (realfunBndr, realfunBody) <- case realfun of
         (Var realfunBndr) -> do
@@ -1059,22 +1071,46 @@
       let [arg1Ty,arg2Ty] = (fst . Type.splitFunTys . CoreUtils.exprType) realfun
       id1 <- Trans.lift $ mkInternalVar "param" arg1Ty
       id2 <- Trans.lift $ mkInternalVar "param" arg2Ty
-      -- Associate initial value with the cloned functions
+      -- Associate initial value with the cloned function
       initbndr <- case initvalue of
         (Var initvalueBndr) -> do
           initBndrMaybe <- Trans.lift $ getGlobalBind initvalueBndr
           case initBndrMaybe of
             (Just a) -> return initvalueBndr
+            -- FIXME: This is definately broken, we're making a top-level binder that
+            -- rerefences a local variable from another function... What we should do
+            -- is copy the value that's referenced by the local variable!
             Nothing -> do
               let body = Var initvalueBndr
               initId <- Trans.lift $ mkBinderFor body ("init" ++ Name.getOccString realfunBndr)
               Trans.lift $ addGlobalBind initId body
               return initId
         otherwise -> do
+          -- FIXME: This is also broken! In case a local variable is referenced anywhere
+          -- in the expression that we're making a top-level binder, we'll again be making
+          -- a reference that the new top-level binder can not find. We should check if
+          -- there are any references to local variables, and copy their values!
           initId <- Trans.lift $ mkBinderFor initvalue ("init" ++ Name.getOccString realfunBndr)
           Trans.lift $ addGlobalBind initId initvalue
           return initId         
       Trans.lift $ MonadState.modify tsInitStates (Map.insert realfunBndr initbndr)
+      -- Associate clock with the clone function
+      clockEdge <- if isLift (appliedF, alreadyMappedArgs) then
+          return (True,1)
+        else do
+          let clock = last valArgs
+          case clock of
+            (Var clockBndr) -> do
+              exprMaybe <- Trans.lift $ getGlobalBind clockBndr
+              let clockExpr = Maybe.fromMaybe (error $ "Normalize.arrowLiftSExtract: could not find clock for: " ++ pprString realfun) exprMaybe
+              let (Var appliedFunBndr, [litArg]) = collectArgs clockExpr
+              clockLit <- Trans.lift $ getIntegerLiteral litArg
+              case (Name.getOccString appliedFunBndr) of
+                "ClockUp" -> return (True,clockLit)
+                "ClockDown" -> return (False,clockLit)
+            otherwise -> do
+              error $ "Normalize.arrowLiftSExtract: Do now know how to handle clock:" ++ show clock
+      Trans.lift $ MonadState.modify tsClocks (Map.insert realfunBndr clockEdge)
       -- Return the extracted expression       
       change (Lam id1 (Lam id2 (App (App realfunBody (Var id1)) (Var id2))))
   where
diff --git a/CLasH/Normalize/NormalizeTools.hs b/CLasH/Normalize/NormalizeTools.hs
--- a/CLasH/Normalize/NormalizeTools.hs
+++ b/CLasH/Normalize/NormalizeTools.hs
@@ -9,7 +9,7 @@
 import qualified Control.Monad as Monad
 import qualified Control.Monad.Trans.Writer as Writer
 import qualified Control.Monad.Trans.Class as Trans
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- GHC API
 import CoreSyn
@@ -278,7 +278,7 @@
   where
   	ty = Id.idType bndr
   	res = case Type.splitTyConApp_maybe ty of
-  		Just (tycon, args) -> Name.getOccString (TyCon.tyConName tycon) == "Stat"
+  		Just (tycon, args) -> Name.getOccString (TyCon.tyConName tycon) == "Comp"
   		Nothing -> False
 
 isArrowE ::
@@ -288,7 +288,7 @@
   where
 	  ty = CoreUtils.exprType expr
 	  res =	case Type.splitTyConApp_maybe ty of
-  		Just (tycon, args) -> (Name.getOccString (TyCon.tyConName tycon)) == "Stat"
+  		Just (tycon, args) -> (Name.getOccString (TyCon.tyConName tycon)) == "Comp"
   		Nothing -> False
 	
 isLift ::
@@ -296,6 +296,12 @@
 	-> Bool
 isLift ((Var bndr), args) = (Name.getOccString bndr) == "^^^" && (length $ CoreTools.get_val_args (Var.varType bndr) args) == 2
 isLift _                  = False
+
+isComponent ::
+	(CoreExpr, [CoreExpr])
+	-> Bool
+isComponent ((Var bndr), args) = (Name.getOccString bndr) == "comp" && (length $ CoreTools.get_val_args (Var.varType bndr) args) == 3
+isComponent _                  = False
 	
 isArrHooks ::
 	(CoreExpr, [CoreExpr])
diff --git a/CLasH/Translator.hs b/CLasH/Translator.hs
--- a/CLasH/Translator.hs
+++ b/CLasH/Translator.hs
@@ -8,9 +8,9 @@
 import qualified Maybe
 import qualified Monad
 import qualified System.FilePath as FilePath
-import qualified Control.Monad.Trans.State as State
+import qualified Control.Monad.Trans.State.Strict as State
 import Text.PrettyPrint.HughesPJ (render)
-import Data.Accessor.Monad.Trans.State
+import Data.Accessor.Monad.Trans.StrictState
 import qualified Data.Map as Map
 import qualified Data.Time.Clock as Clock
 import Debug.Trace
@@ -114,7 +114,7 @@
   uniqSupply <- UniqSupply.mkSplitUniqSupply 'z'
   let init_typedecls = map (mktydecl . Maybe.fromJust . snd) $ Map.toList builtin_types
   let init_typestate = TypeState builtin_types init_typedecls Map.empty Map.empty env
-  let init_state = TranslatorState uniqSupply init_typestate Map.empty Map.empty 0 Map.empty Map.empty Map.empty 0 Map.empty
+  let init_state = TranslatorState uniqSupply init_typestate Map.empty Map.empty 0 Map.empty Map.empty Map.empty 0 Map.empty Map.empty
   return $ State.evalState session init_state
 
 -- | Prepares the directory for writing VHDL files. This means creating the
diff --git a/CLasH/Translator/TranslatorTypes.hs b/CLasH/Translator/TranslatorTypes.hs
--- a/CLasH/Translator/TranslatorTypes.hs
+++ b/CLasH/Translator/TranslatorTypes.hs
@@ -6,10 +6,10 @@
 module CLasH.Translator.TranslatorTypes where
 
 -- Standard modules
-import qualified Control.Monad.Trans.State as State
+import qualified Control.Monad.Trans.State.Strict as State
 import qualified Data.Map as Map
 import qualified Data.Accessor.Template
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- GHC API
 import qualified GHC
@@ -17,6 +17,7 @@
 import qualified Type
 import qualified HscTypes
 import qualified UniqSupply
+import qualified TyCon
 
 -- VHDL Imports
 import qualified Language.VHDL.AST as AST
@@ -72,7 +73,7 @@
 -- VHDLId of the function and the function body.
 type TypeFunMap = Map.Map (HType, String) (AST.VHDLId, AST.SubProgBody)
 
-type TfpIntMap = Map.Map OrdType Int
+type TfpIntMap = Map.Map TyCon.TyCon Int
 -- A substate that deals with type generation
 data TypeState = TypeState {
   -- | A map of Core type -> VHDL Type
@@ -102,6 +103,7 @@
   , tsInitStates_ :: Map.Map CoreSyn.CoreBndr CoreSyn.CoreBndr
   , tsTransformCounter_ :: Int -- ^ How many transformations were applied?
   , tsArrows_ :: Map.Map CoreSyn.CoreBndr CoreSyn.CoreBndr
+  , tsClocks_ :: Map.Map CoreSyn.CoreBndr (Bool,Integer)
 }
 
 -- Derive accessors
diff --git a/CLasH/Utils.hs b/CLasH/Utils.hs
--- a/CLasH/Utils.hs
+++ b/CLasH/Utils.hs
@@ -3,10 +3,10 @@
 -- Standard Imports
 import qualified Maybe
 import Data.Accessor
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 import qualified Data.Map as Map
 import qualified Control.Monad as Monad
-import qualified Control.Monad.Trans.State as State
+import qualified Control.Monad.Trans.State.Strict as State
 import qualified Debug.Trace as Trace
   
 -- Make a caching version of a stateful computatation.
diff --git a/CLasH/Utils/Core/BinderTools.hs b/CLasH/Utils/Core/BinderTools.hs
--- a/CLasH/Utils/Core/BinderTools.hs
+++ b/CLasH/Utils/Core/BinderTools.hs
@@ -4,7 +4,7 @@
 module CLasH.Utils.Core.BinderTools where
 
 -- Standard modules
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- GHC API
 import qualified CoreSyn
@@ -37,7 +37,7 @@
 mkInternalVar :: String -> Type.Type -> TranslatorSession Var.Var
 mkInternalVar str ty = do
   uniq <- mkUnique
-  let occname = OccName.mkVarOcc (str ++ show uniq)
+  let occname = OccName.mkVarOcc str
   let name = Name.mkInternalName uniq occname SrcLoc.noSrcSpan
   return $ Var.mkLocalVar IdInfo.VanillaId name ty IdInfo.vanillaIdInfo
 
@@ -48,7 +48,7 @@
 mkTypeVar :: String -> Type.Kind -> TranslatorSession Var.Var
 mkTypeVar str kind = do
   uniq <- mkUnique
-  let occname = OccName.mkVarOcc (str ++ show uniq)
+  let occname = OccName.mkVarOcc str
   let name = Name.mkInternalName uniq occname SrcLoc.noSrcSpan
   return $ Var.mkTyVar name kind
 
diff --git a/CLasH/Utils/Core/CoreTools.hs b/CLasH/Utils/Core/CoreTools.hs
--- a/CLasH/Utils/Core/CoreTools.hs
+++ b/CLasH/Utils/Core/CoreTools.hs
@@ -10,7 +10,7 @@
 import qualified List
 import qualified System.IO.Unsafe
 import qualified Data.Map as Map
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- GHC API
 import qualified GHC
@@ -35,7 +35,9 @@
 import qualified Literal
 import qualified MkCore
 import qualified VarEnv
+import qualified VarSet
 import qualified Outputable
+import qualified TypeRep
 
 -- Local imports
 import CLasH.Translator.TranslatorTypes
@@ -52,35 +54,178 @@
 -- | Evaluate a core Type representing type level int from the tfp
 -- library to a real int. Checks if the type really is a Dec type and
 -- caches the results.
+-- tfp_to_int :: Type.Type -> TypeSession Int
+-- tfp_to_int ty = do
+--   hscenv <- MonadState.get tsHscEnv
+--   let norm_ty = normalize_tfp_int hscenv ty
+--   case Type.splitTyConApp_maybe norm_ty of
+--     Just (tycon, args) -> do
+--       let name = Name.getOccString (TyCon.tyConName tycon)
+--       case name of
+--         "Dec" ->
+--           tfp_to_int' ty
+--         otherwise -> do
+--           return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
+--     Nothing -> return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
 tfp_to_int :: Type.Type -> TypeSession Int
-tfp_to_int ty = do
-  hscenv <- MonadState.get tsHscEnv
-  let norm_ty = normalize_tfp_int hscenv ty
-  case Type.splitTyConApp_maybe norm_ty of
-    Just (tycon, args) -> do
-      let name = Name.getOccString (TyCon.tyConName tycon)
-      case name of
-        "Dec" ->
-          tfp_to_int' ty
-        otherwise -> do
-          return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
-    Nothing -> return $ error ("Callin tfp_to_int on non-dec:" ++ (show ty))
+tfp_to_int ty = tfp_to_int' (pprString ty ++ "\n") ty
 
+tfp_to_int' :: String -> Type.Type -> TypeSession Int
+tfp_to_int' msg ty@(TypeRep.TyConApp tycon args) = if (TyCon.isClosedSynTyCon tycon) && (null args) then do
+    lens <- MonadState.get tsTfpInts
+    let knownSynonymMaybe = Map.lookup tycon lens
+    case knownSynonymMaybe of
+      Just knownSynonym -> return knownSynonym
+      Nothing -> do
+        let tycon' = TyCon.synTyConType tycon
+        len <- tycon' `seq` tfp_to_int' (msg ++ " > " ++ (Name.getOccString (TyCon.tyConName tycon))) $! tycon'
+        len `seq` MonadState.modify tsTfpInts $! (Map.insert tycon len)
+        return len
+  else if (TyCon.isClosedSynTyCon tycon) then do
+    let tyconNameString = Name.getOccString (TyCon.tyConName tycon)
+    case tyconNameString of
+      -- TODO: Add more cases for type synonyms introduced by the Renamer
+      -- Especially for those cases where there are more type arguments
+      -- than type variables, which will throw an error if not not caught.
+      "R:IfFalseyz" -> do
+        let arg = args!!1
+        len <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconNameString) $! arg
+        return len
+      "R:IfTrueyz" -> do
+        let arg = head args
+        len <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconNameString) $! arg
+        return len
+      -- FIXME: substitution of type variables by type arguments is potentially
+      -- wrong!! Check if there are cases when this is valid. If not, throw an
+      -- Error if we do not know the syntycon name!
+      -- FIXED: It should be valid in all cases as we are replacing type variables
+      -- on the RHS of the type synonym. So no additional logic/arithmatic is needed.
+      _ -> do {
+              ; let { ty'  = TyCon.synTyConType tycon
+                    ; tyvarSet = VarSet.varSetElems $ Type.tyVarsOfType ty'
+                    ; ty''  = let
+                                tysubst = if length args == length tyvarSet then
+                                    Type.zipTopTvSubst tyvarSet args
+                                  else
+                                    error $ "CoreTools.tfp_to_int': TyVars(" ++ (show $ length tyvarSet) ++ ") and Args(" ++ (show $ length args) ++ 
+                                            ") don't match for: " ++ tyconNameString ++ "\nContext: " ++ msg
+                              in
+                                Type.substTy tysubst ty'
+                    }            
+              ; len <- (Type.seqType ty'') `seq` tfp_to_int' (msg ++ " > " ++ tyconNameString) $! ty''
+              ; return len
+              }
+  else do
+    let tyconName = pprString tycon
+    let tyconNameString = Name.getOccString (TyCon.tyConName tycon)
+    case tyconNameString of
+      "Dec" -> do
+        let arg = head args
+        len <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        return len
+      ":."  -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len  = int0 `seq` int1 `seq` int0 * 10 + int1
+        return len
+      "DecN" -> return 0
+      "Dec0" -> return 0
+      "Dec1" -> return 1
+      "Dec2" -> return 2
+      "Dec3" -> return 3
+      "Dec4" -> return 4
+      "Dec5" -> return 5
+      "Dec6" -> return 6
+      "Dec7" -> return 7
+      "Dec8" -> return 8
+      "Dec9" -> return 9
+      "Succ" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let len = int `seq` int + 1
+        return len
+      "Pred" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let len = int `seq` int - 1
+        return len
+      ":+:" -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len  = int0 `seq` int1 `seq` int0 + int1
+        return len
+      ":-:" -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len  = int0 `seq` int1 `seq` int0 - int1
+        return len
+      ":*:" -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len  = int0 `seq` int1 `seq` int0 * int1
+        return len
+      "Pow2" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let len = int `seq` int * int
+        return len
+      "Mul2" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let len = int `seq` int + int
+        return len
+      "Div2" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let len = int `seq` int `div` 2
+        return len
+      "Fac" -> do
+        let arg = head args
+        int <- arg `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg
+        let fac x = if x == 0 then 1 else x * fac (x - 1)
+        let len = int `seq` fac int
+        return len
+      "Min" -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len = int0 `seq` int1 `seq` if int0 <= int1 then int0 else int1
+        return len
+      "Max" -> do
+        let arg0 = head args
+        let arg1 = args!!1
+        int0 <- arg0 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg0
+        int1 <- arg1 `seq` tfp_to_int' (msg ++ " > " ++ tyconName) $! arg1
+        let len = int0 `seq` int1 `seq` if int0 >= int1 then int0 else int1
+        return len
+      _ -> error $ "CoreTools.tfp_to_int: Unknown TyCon : " ++ pprString tycon ++ "\n Context: " ++ msg
+tfp_to_int' msg ty = error $ "CoreTools.tfp_to_int: Not a TyConApp: " ++ show ty ++ "\n Context: " ++ msg
+
+
 -- | Evaluate a core Type representing type level int from the tfp
 -- library to a real int. Caches the results. Do not use directly, use
 -- tfp_to_int instead.
-tfp_to_int' :: Type.Type -> TypeSession Int
-tfp_to_int' ty = do
-  lens <- MonadState.get tsTfpInts
-  hscenv <- MonadState.get tsHscEnv
-  let norm_ty = normalize_tfp_int hscenv ty
-  let existing_len = Map.lookup (OrdType norm_ty) lens
-  case existing_len of
-    Just len -> return len
-    Nothing -> do
-      let new_len = eval_tfp_int hscenv ty
-      MonadState.modify tsTfpInts (Map.insert (OrdType norm_ty) (new_len))
-      return new_len
+-- tfp_to_int' :: Type.Type -> TypeSession Int
+-- tfp_to_int' ty = do
+--   lens <- MonadState.get tsTfpInts
+--   hscenv <- MonadState.get tsHscEnv
+--   let norm_ty = normalize_tfp_int hscenv ty
+--   let existing_len = Map.lookup (OrdType norm_ty) lens
+--   case existing_len of
+--     Just len -> return len
+--     Nothing -> do
+--       let new_len = eval_tfp_int hscenv ty
+--       MonadState.modify tsTfpInts (Map.insert (OrdType norm_ty) (new_len))
+--       return new_len
       
 -- | Evaluate a core Type representing type level int from the tfp
 -- library to a real int. Do not use directly, use tfp_to_int instead.
@@ -259,6 +404,7 @@
   case CoreSyn.collectArgs expr of
     (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachInt integer)]) 
       | getFullString f == "GHC.Integer.smallInteger" -> return integer
+      | getFullString f == "GHC.Types.I#" -> return integer
     (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachInt64 integer)]) 
       | getFullString f == "GHC.Integer.int64ToInteger" -> return integer
     (CoreSyn.Var f, [CoreSyn.Lit (Literal.MachWord integer)]) 
diff --git a/CLasH/VHDL.hs b/CLasH/VHDL.hs
--- a/CLasH/VHDL.hs
+++ b/CLasH/VHDL.hs
@@ -8,7 +8,7 @@
 import qualified Maybe
 import qualified Control.Arrow as Arrow
 import Data.Accessor
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- VHDL Imports
 import qualified Language.VHDL.AST as AST
diff --git a/CLasH/VHDL/Constants.hs b/CLasH/VHDL/Constants.hs
--- a/CLasH/VHDL/Constants.hs
+++ b/CLasH/VHDL/Constants.hs
@@ -16,10 +16,17 @@
              , negateId, minusId, fromSizedWordId, fromIntegerId, resizeWordId
              , resizeIntId, sizedIntId, smallIntegerId, fstId, sndId, blockRAMId
              , splitId, minimumId, fromRangedWordId, xorId, shiftLId , shiftRId
+             , u2bvId, s2bvId, bv2sId, bv2uId
              ]
 --------------
 -- Identifiers
 --------------
+
+u2bvId, s2bvId, bv2sId, bv2uId :: String
+u2bvId = "u2bv"
+s2bvId = "s2bv"
+bv2sId = "bv2s"
+bv2uId = "bv2u"
 
 -- | reset and clock signal identifiers in String form
 resetStr, clockStr :: String
diff --git a/CLasH/VHDL/Generate.hs b/CLasH/VHDL/Generate.hs
--- a/CLasH/VHDL/Generate.hs
+++ b/CLasH/VHDL/Generate.hs
@@ -3,10 +3,11 @@
 -- Standard modules
 import qualified Data.List as List
 import qualified Data.Map as Map
+import qualified Data.Set as Set
 import qualified Control.Monad as Monad
 import qualified Maybe
 import qualified Data.Either as Either
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- VHDL Imports
 import qualified Language.VHDL.AST as AST
@@ -52,7 +53,9 @@
       count <- MonadState.get tsEntityCounter 
       let vhdl_id = mkVHDLBasicId $ varToString fname ++ "Component_" ++ show count
       MonadState.set tsEntityCounter (count + 1)
-      let ent_decl = createEntityAST vhdl_id args' res'
+      clocks <- MonadState.get tsClocks
+      let clockList = (Set.toList . Set.fromList . Map.elems) clocks
+      let ent_decl = createEntityAST vhdl_id clockList args' res'
       let signature = Entity vhdl_id args' res' ent_decl
       return signature
   where
@@ -79,19 +82,21 @@
 -- | Create the VHDL AST for an entity
 createEntityAST ::
   AST.VHDLId                   -- ^ The name of the function
+  -> [(Bool,Integer)]          -- ^ Clocks
   -> [Port]                    -- ^ The entity's arguments
   -> Maybe Port                -- ^ The entity's result
   -> AST.EntityDec             -- ^ The entity with the ent_decl filled in as well
 
-createEntityAST vhdl_id args res =
+createEntityAST vhdl_id clocks args res =
   AST.EntityDec vhdl_id ports
   where
     -- Create a basic Id, since VHDL doesn't grok filenames with extended Ids.
     ports = map (mkIfaceSigDec AST.In) args
               ++ (Maybe.maybeToList res_port)
-              ++ [clk_port,resetn_port]
-    -- Add a clk port if we have state
-    clk_port = AST.IfaceSigDec clockId AST.In std_logicTM
+              ++ clkPorts
+              ++ [resetn_port]
+    -- TODO: Only add a clk ports if we have state
+    clkPorts = map ((\a -> AST.IfaceSigDec a AST.In std_logicTM) . AST.unsafeVHDLBasicId . ("clock" ++) . show . snd) clocks
     resetn_port = AST.IfaceSigDec resetId AST.In std_logicTM
     res_port = fmap (mkIfaceSigDec AST.Out) res
 
@@ -130,7 +135,10 @@
   let (statementss, used_entitiess) = unzip sms
   -- Get initial state, if it's there
   initSmap <- MonadState.get tsInitStates
-  let init_state = Map.lookup (fname) initSmap
+  let init_state = Map.lookup fname initSmap
+  -- Get clock domains, if they're there
+  clocksMap <- MonadState.get tsClocks
+  let clockEdge = Map.lookup fname clocksMap
   -- Create a state proc, if needed
   (state_proc, resbndr) <- case (Maybe.catMaybes in_state_maybes, Maybe.catMaybes out_state_maybes, init_state) of
         ([in_state], [out_state], Nothing) -> do 
@@ -141,7 +149,7 @@
         ([in_state], [out_state], Just resetval) -> do
           nonEmpty <- hasNonEmptyType "" in_state
           if nonEmpty 
-            then mkStateProcSm (in_state, out_state, resetval)            
+            then mkStateProcSm (in_state, out_state, resetval, Maybe.fromMaybe (error $ "Generate.getArchitecture: No clock found for: " ++ show fname ++ ", listed clocks: " ++ show clocksMap) clockEdge)            
             else do
               nonEmptyReset <- hasNonEmptyType "" resetval
               if nonEmptyReset
@@ -178,9 +186,9 @@
       return ((Nothing, Nothing), sms)
 
 mkStateProcSm :: 
-  (CoreSyn.CoreBndr, CoreSyn.CoreBndr, CoreSyn.CoreBndr) -- ^ The current state, new state and reset variables
+  (CoreSyn.CoreBndr, CoreSyn.CoreBndr, CoreSyn.CoreBndr, (Bool, Integer)) -- ^ The current state, new state, reset variables, and clock domain
   -> TranslatorSession ([AST.ConcSm], [CoreSyn.CoreBndr]) -- ^ The resulting statements
-mkStateProcSm (old, new, res) = do
+mkStateProcSm (old, new, res, (edge, period)) = do
   let error_msg = "\nVHDL.mkSigDec: Can not make signal declaration for type: \n" ++ pprString res 
   type_mark_old_maybe <- MonadState.lift tsType $ vhdlTy error_msg (Var.varType old)
   let type_mark_old = Maybe.fromMaybe 
@@ -201,16 +209,20 @@
   let blocklabel       = mkVHDLBasicId "state"
   let statelabel  = mkVHDLBasicId "stateupdate"
   let rising_edge = AST.NSimple $ mkVHDLBasicId "rising_edge"
+  let falling_edge = AST.NSimple $ mkVHDLBasicId "falling_edge"
   let wform       = AST.Wform [AST.WformElem (AST.PrimName $ varToVHDLName new) Nothing]
   let clk_assign      = AST.SigAssign (varToVHDLName old) wform
-  let rising_edge_clk = AST.PrimFCall $ AST.FCall rising_edge [Nothing AST.:=>: (AST.ADName $ AST.NSimple clockId)]
+  let clockId = AST.unsafeVHDLBasicId ("clock" ++ show period)
+  let clkFlank = AST.PrimFCall $ AST.FCall (if edge then rising_edge else falling_edge) [Nothing AST.:=>: (AST.ADName $ AST.NSimple clockId)]
   let resetn_is_low  = (AST.PrimName $ AST.NSimple resetId) AST.:=: (AST.PrimLit "'0'")
   signature <- getEntity res
   let entity_id = ent_id signature
   let reslabel = "resetval_" ++ ((prettyShow . varToVHDLName) res)
   let portmaps = mkAssocElems [] (AST.NSimple resvalid) signature
-  let reset_statement = mkComponentInst reslabel entity_id portmaps
-  let clk_statement = [AST.ElseIf rising_edge_clk [clk_assign]]
+  clocksMap <- MonadState.get tsClocks
+  let clockDomains = ((map snd) . Set.toList . Set.fromList . Map.elems) clocksMap
+  let reset_statement = mkComponentInst reslabel entity_id clockDomains portmaps
+  let clk_statement = [AST.ElseIf clkFlank [clk_assign]]
   let statement   = AST.IfSm resetn_is_low [res_assign] clk_statement Nothing
   let stateupdate = AST.CSPSm $ AST.ProcSm statelabel [clockId,resetId,resvalid] [statement]
   let block = AST.CSBSm $ AST.BlockSm blocklabel [] (AST.PMapAspect []) [resvaldec] [reset_statement,stateupdate]
@@ -874,6 +886,17 @@
         }
   ; return [out_assign]
   }
+
+genCopyn :: BuiltinBuilder 
+genCopyn = genNoInsts genCopyn'
+genCopyn' :: (Either CoreSyn.CoreBndr AST.VHDLName ) -> CoreSyn.CoreBndr -> [(Either CoreSyn.CoreExpr AST.Expr, Type.Type)] -> TranslatorSession [AST.ConcSm]
+genCopyn' (Left res) f [arg0,(arg,argType)] = do {
+  ; [arg'] <- argsToVHDLExprs [arg]
+  ; let { resExpr = AST.Aggregate [AST.ElemAssoc (Just AST.Others) arg']
+        ; out_assign = mkUncondAssign (Left res) resExpr
+        }
+  ; return [out_assign]
+  }
     
 genConcat :: BuiltinBuilder
 genConcat = genNoInsts genConcat'
@@ -1027,6 +1050,7 @@
   return [AST.CSBSm block]
   where
     ram_id = mkVHDLBasicId "ram"
+    clockId = AST.unsafeVHDLBasicId "clock1"
     mkUpdateProcSm :: AST.ConcSm
     mkUpdateProcSm = AST.CSPSm $ AST.ProcSm proclabel [clockId] [statement]
       where
@@ -1082,6 +1106,56 @@
   ; return $ (genExprFCall2 (mkVHDLBasicId "shift_right") (arg1, (genExprFCall (mkVHDLBasicId toIntegerId) arg2)))
   }
 
+genI2bv :: BuiltinBuilder
+genI2bv = genNoInsts $ genExprArgs $ genExprRes genI2bv'
+genI2bv' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [(AST.Expr, Type.Type)] -> TranslatorSession AST.Expr
+genI2bv' (Left res) f [(arg1,_)] = do {
+  ; let resTy = Var.varType res
+  ; let errorMsg = "\nGenerate.genS2bv': Can not construct vector type: " ++ pprString resTy 
+  -- TODO: Handle Nothing
+  ; Just tmpVhdlTy <- MonadState.lift tsType $ vhdlTy errorMsg resTy
+  ; return $ (genExprFCall (mkVHDLBasicId $ AST.fromVHDLId tmpVhdlTy) arg1)
+  }
+
+genBV2u :: BuiltinBuilder
+genBV2u = genNoInsts $ genExprArgs $ genExprRes genBV2u'
+genBV2u' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [(AST.Expr, Type.Type)] -> TranslatorSession AST.Expr
+genBV2u' (Left res) f [(arg1,_)] = do {
+  ; return $ (genExprFCall (mkVHDLBasicId "unsigned") arg1)
+  }
+
+genBV2s :: BuiltinBuilder
+genBV2s = genNoInsts $ genExprArgs $ genExprRes genBV2s'
+genBV2s' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [(AST.Expr, Type.Type)] -> TranslatorSession AST.Expr
+genBV2s' (Left res) f [(arg1,_)] = do {
+  ; return $ (genExprFCall (mkVHDLBasicId "signed") arg1)
+  }
+
+genTake :: BuiltinBuilder
+genTake = genNoInsts $ genExprRes genTake'
+genTake' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [(Either CoreSyn.CoreExpr AST.Expr, Type.Type)] -> TranslatorSession AST.Expr
+genTake' res f [(arg1,arg1Type),(arg2,arg2Type)] = do {
+  ; literal <- MonadState.lift tsType $ tfp_to_int arg1Type
+  ; arg2expr <- argToVHDLExpr arg2
+  ; let (AST.PrimName arg2name) = Maybe.fromMaybe (error $ "Generate.genTake': Expected variable reference, but found:" ++ either pprString show arg2) arg2expr
+  ; arg2len <- MonadState.lift tsType $ tfp_to_int $ tfvec_len_ty arg2Type
+  ; let minLit = min literal arg2len
+  ; let takeVal = AST.PrimName (AST.NSlice (AST.SliceName arg2name (AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (minLit - 1)))))
+  ; return takeVal
+  }
+
+genDrop :: BuiltinBuilder
+genDrop = genNoInsts $ genExprRes genDrop'
+genDrop' :: Either CoreSyn.CoreBndr AST.VHDLName -> CoreSyn.CoreBndr -> [(Either CoreSyn.CoreExpr AST.Expr, Type.Type)] -> TranslatorSession AST.Expr
+genDrop' res f [(arg1,arg1Type),(arg2,arg2Type)] = do {
+  ; literal <- MonadState.lift tsType $ tfp_to_int arg1Type
+  ; arg2expr <- argToVHDLExpr arg2
+  ; let (AST.PrimName arg2name) = Maybe.fromMaybe (error $ "Generate.genDrop': Expected variable reference, but found:" ++ either pprString show arg2) arg2expr
+  ; arg2len <- MonadState.lift tsType $ tfp_to_int $ tfvec_len_ty arg2Type
+  ; let dropVal = AST.PrimName (AST.NSlice (AST.SliceName arg2name (AST.ToRange (AST.PrimLit $ show literal) (AST.PrimLit $ show (arg2len - 1)))))
+  ; return dropVal
+  }
+
 -----------------------------------------------------------------------------
 -- Function to generate VHDL for applications
 -----------------------------------------------------------------------------
@@ -1191,9 +1265,11 @@
                     let entity_id = ent_id signature
                     -- TODO: Using show here isn't really pretty, but we'll need some
                     -- unique-ish value...
-                    let label = "comp_ins_" ++ (either show prettyShow) dst
+                    let label = "comp_ins_" ++ (either (prettyShow . varToVHDLName) prettyShow) dst
                     let portmaps = mkAssocElems args' ((either varToVHDLName id) dst) signature
-                    return ([mkComponentInst label entity_id portmaps], [f])
+                    clocksMap <- MonadState.get tsClocks
+                    let clockDomains = ((map snd) . Set.toList . Set.fromList . Map.elems) clocksMap
+                    return ([mkComponentInst label entity_id clockDomains portmaps], [f])
                   else
                     -- Not a top level binder, so this must be a local variable reference.
                     -- It should have a representable type (and thus, no arguments) and a
@@ -1232,7 +1308,9 @@
                -- unique-ish value...
                let label = "comp_ins_" ++ (either (prettyShow . varToVHDLName) prettyShow) dst
                let portmaps = mkAssocElems args' ((either varToVHDLName id) dst) signature
-               return ([mkComponentInst label entity_id portmaps], [f])
+               clocksMap <- MonadState.get tsClocks
+               let clockDomains = ((map snd) . Set.toList . Set.fromList . Map.elems) clocksMap
+               return ([mkComponentInst label entity_id clockDomains portmaps], [f])
             else
               -- Not a top level binder, so this must be a local variable reference.
               -- It should have a representable type (and thus, no arguments) and a
@@ -1292,12 +1370,9 @@
   , (lastId, (AST.SubProgBody lastSpec    []                  [lastExpr],[]))
   , (initId, (AST.SubProgBody initSpec    [AST.SPVD initVar]  [initExpr, initRet],[]))
   , (minimumId, (AST.SubProgBody minimumSpec [] [minimumExpr],[]))
-  , (takeId, (AST.SubProgBody takeSpec    [AST.SPVD takeVar]  [takeExpr, takeRet],[minimumId]))
-  , (dropId, (AST.SubProgBody dropSpec    [AST.SPVD dropVar]  [dropExpr, dropRet],[]))
   , (plusgtId, (AST.SubProgBody plusgtSpec  [AST.SPVD plusgtVar] [plusgtExpr, plusgtRet],[]))
   , (emptyId, (AST.SubProgBody emptySpec   [AST.SPVD emptyVar] [emptyExpr],[]))
   , (singletonId, (AST.SubProgBody singletonSpec [AST.SPVD singletonVar] [singletonRet],[]))
-  , (copynId, (AST.SubProgBody copynSpec    [AST.SPVD copynVar]      [copynExpr],[]))
   , (selId, (AST.SubProgBody selSpec  [AST.SPVD selVar] [selFor, selRet],[]))
   , (ltplusId, (AST.SubProgBody ltplusSpec [AST.SPVD ltplusVar] [ltplusExpr, ltplusRet],[]))  
   , (plusplusId, (AST.SubProgBody plusplusSpec [AST.SPVD plusplusVar] [plusplusExpr, plusplusRet],[]))
@@ -1381,45 +1456,12 @@
                         []
                         (Just $ AST.Else [minimumExprRet])
       where minimumExprRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple rightPar)
-    takeSpec = AST.Function (mkVHDLExtId takeId) [AST.IfaceVarDec nPar   naturalTM,
-                                   AST.IfaceVarDec vecPar vectorTM ] vectorTM
        -- variable res : fsvec_x (0 to (minimum (n,vec'length))-1);
     minLength = AST.PrimFCall $ AST.FCall (AST.NSimple (mkVHDLExtId minimumId))  
                               [Nothing AST.:=>: AST.ADExpr (AST.PrimName $ AST.NSimple nPar)
                               ,Nothing AST.:=>: AST.ADExpr (AST.PrimName (AST.NAttribute $ 
                                 AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing))]
-    takeVar = 
-         AST.VarDec resId 
-                (AST.SubtypeIn vectorTM
-                  (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
-                   [AST.ToRange (AST.PrimLit "0")
-                               (minLength AST.:-:
-                                (AST.PrimLit "1"))   ]))
-                Nothing
-       -- res AST.:= vec(0 to n-1)
-    takeExpr = AST.NSimple resId AST.:= 
-                    (vecSlice (AST.PrimLit "0") 
-                              (minLength AST.:-: AST.PrimLit "1"))
-    takeRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-    dropSpec = AST.Function (mkVHDLExtId dropId) [AST.IfaceVarDec nPar   naturalTM,
-                                   AST.IfaceVarDec vecPar vectorTM ] vectorTM 
-       -- variable res : fsvec_x (0 to vec'length-n-1);
-    dropVar = 
-         AST.VarDec resId 
-                (AST.SubtypeIn vectorTM
-                  (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
-                   [AST.ToRange (AST.PrimLit "0")
-                            (AST.PrimName (AST.NAttribute $ 
-                              AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) AST.:-:
-                               (AST.PrimName $ AST.NSimple nPar)AST.:-: (AST.PrimLit "1")) ]))
-               Nothing
-       -- res AST.:= vec(n to vec'length-1)
-    dropExpr = AST.NSimple resId AST.:= (vecSlice 
-                               (AST.PrimName $ AST.NSimple nPar) 
-                               (AST.PrimName (AST.NAttribute $ 
-                                  AST.AttribName (AST.NSimple vecPar) (AST.NSimple $ mkVHDLBasicId lengthId) Nothing) 
-                                                             AST.:-: AST.PrimLit "1"))
-    dropRet =  AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
+
     plusgtSpec = AST.Function (mkVHDLExtId plusgtId) [AST.IfaceVarDec aPar   elemTM,
                                        AST.IfaceVarDec vecPar vectorTM] vectorTM 
     -- variable res : fsvec_x (0 to vec'length);
@@ -1454,20 +1496,7 @@
              (Just $ AST.Aggregate [AST.ElemAssoc (Just AST.Others) 
                                           (AST.PrimName $ AST.NSimple aPar)])
     singletonRet = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
-    copynSpec = AST.Function (mkVHDLExtId copynId) [AST.IfaceVarDec nPar   naturalTM,
-                                   AST.IfaceVarDec aPar   elemTM   ] vectorTM 
-    -- variable res : fsvec_x (0 to n-1) := (others => a);
-    copynVar = 
-      AST.VarDec resId 
-             (AST.SubtypeIn vectorTM
-               (Just $ AST.ConstraintIndex $ AST.IndexConstraint 
-                [AST.ToRange (AST.PrimLit "0")
-                            ((AST.PrimName (AST.NSimple nPar)) AST.:-:
-                             (AST.PrimLit "1"))   ]))
-             (Just $ AST.Aggregate [AST.ElemAssoc (Just AST.Others) 
-                                          (AST.PrimName $ AST.NSimple aPar)])
-    -- return res
-    copynExpr = AST.ReturnSm (Just $ AST.PrimName $ AST.NSimple resId)
+
     selSpec = AST.Function (mkVHDLExtId selId) [AST.IfaceVarDec fPar   naturalTM,
                                AST.IfaceVarDec sPar   naturalTM,
                                AST.IfaceVarDec nPar   naturalTM,
@@ -1671,14 +1700,14 @@
 -- it to VHDL.Constants/builtinIds as well.
 globalNameTable :: NameTable
 globalNameTable = Map.fromList
-  [ (exId             , (2, genFCall True          ) )
+  [ (exId             , (2, genFCall True           ) )
   , (replaceId        , (3, genFCall False          ) )
   , (headId           , (1, genFCall True           ) )
   , (lastId           , (1, genFCall True           ) )
   , (tailId           , (1, genFCall False          ) )
   , (initId           , (1, genFCall False          ) )
-  , (takeId           , (2, genFCall False          ) )
-  , (dropId           , (2, genFCall False          ) )
+  , (takeId           , (2, genTake                 ) )
+  , (dropId           , (2, genDrop                 ) )
   , (selId            , (4, genFCall False          ) )
   , (plusgtId         , (2, genFCall False          ) )
   , (ltplusId         , (2, genFCall False          ) )
@@ -1701,7 +1730,7 @@
   , (generateId       , (2, genGenerate             ) )
   , (emptyId          , (0, genFCall False          ) )
   , (singletonId      , (1, genFCall False          ) )
-  , (copynId          , (2, genFCall False          ) )
+  , (copynId          , (2, genCopyn                ) )
   , (copyId           , (1, genCopy                 ) )
   , (lengthTId        , (1, genFCall False          ) )
   , (nullId           , (1, genFCall False          ) )
@@ -1736,6 +1765,10 @@
   , (xorId            , (2, genOperator2 AST.Xor    ) )
   , (shiftLId         , (2, genSll                  ) )
   , (shiftRId         , (2, genSra                  ) )
+  , (s2bvId           , (1, genI2bv                 ) )
+  , (u2bvId           , (1, genI2bv                 ) )
+  , (bv2uId           , (1, genBV2u                 ) )
+  , (bv2sId           , (1, genBV2s                 ) )
   --, (tfvecId          , (1, genTFVec                ) )
   , (minimumId        , (2, error "\nFunction name: \"minimum\" is used internally, use another name"))
   ]
diff --git a/CLasH/VHDL/Testbench.hs b/CLasH/VHDL/Testbench.hs
--- a/CLasH/VHDL/Testbench.hs
+++ b/CLasH/VHDL/Testbench.hs
@@ -7,7 +7,7 @@
 import qualified Control.Monad as Monad
 import qualified Maybe
 import qualified Data.Map as Map
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- VHDL Imports
 import qualified Language.VHDL.AST as AST
@@ -78,11 +78,12 @@
         -- used by mkAssocElems when there is no output port.
         Nothing -> (undefined, [], [])
   let iDecs   = map (\(vId, tm) -> AST.SigDec vId tm Nothing) iIface
+  let clockId = AST.unsafeVHDLBasicId ("clock1")
   let finalIDecs = iDecs ++
                     [AST.SigDec clockId std_logicTM (Just $ AST.PrimLit "'0'"),
                      AST.SigDec resetId std_logicTM (Just $ AST.PrimLit "'0'")]
   let portmaps = mkAssocElems (map idToVHDLExpr iIds) (AST.NSimple oId) signature
-  let mIns    = mkComponentInst "totest" entId portmaps
+  let mIns    = mkComponentInst "totest" entId [1] portmaps
   (stimuliAssigns, stimuliDecs, cycles, used) <- createStimuliAssigns mCycles stimuli (head iIds)
   let finalAssigns = (AST.CSSASm (AST.NSimple resetId AST.:<==:
                       AST.ConWforms []
@@ -146,7 +147,8 @@
 -- | generates a clock process with a period of 10ns
 createClkProc :: AST.ProcSm
 createClkProc = AST.ProcSm (AST.unsafeVHDLBasicId "clkproc") [] sms
- where sms = -- wait for 5 ns -- (half a cycle)
+ where clockId = AST.unsafeVHDLBasicId ("clock1")
+       sms = -- wait for 5 ns -- (half a cycle)
              [AST.WaitFor $ AST.PrimLit "5 ns",
               -- clk <= not clk;
               AST.NSimple clockId `AST.SigAssign` 
@@ -159,7 +161,8 @@
   AST.ProcSm (AST.unsafeVHDLBasicId "writeoutput") 
          [clockId]
          [AST.IfSm clkPred (writeOuts outs) [] Nothing]
- where clkPred = AST.PrimName (AST.NAttribute $ AST.AttribName (AST.NSimple clockId) 
+ where clockId = AST.unsafeVHDLBasicId ("clock1")
+       clkPred = AST.PrimName (AST.NAttribute $ AST.AttribName (AST.NSimple clockId) 
                                                    (AST.NSimple eventId)
                                                    Nothing          ) `AST.And` 
                  (AST.PrimName (AST.NSimple clockId) AST.:=: AST.PrimLit "'1'")
diff --git a/CLasH/VHDL/VHDLTools.hs b/CLasH/VHDL/VHDLTools.hs
--- a/CLasH/VHDL/VHDLTools.hs
+++ b/CLasH/VHDL/VHDLTools.hs
@@ -8,7 +8,7 @@
 import qualified Data.Char as Char
 import qualified Data.Map as Map
 import qualified Control.Monad as Monad
-import qualified Data.Accessor.Monad.Trans.State as MonadState
+import qualified Data.Accessor.Monad.Trans.StrictState as MonadState
 
 -- VHDL Imports
 import qualified Language.VHDL.AST as AST
@@ -24,6 +24,7 @@
 import qualified DataCon
 import qualified CoreSubst
 import qualified Outputable
+import qualified Unique
 
 -- Local imports
 import CLasH.VHDL.VHDLTypes
@@ -132,14 +133,15 @@
 mkComponentInst ::
   String -- ^ The portmap label
   -> AST.VHDLId -- ^ The entity name
+  -> [Integer] -- ^ Clock domains
   -> [AST.AssocElem] -- ^ The port assignments
   -> AST.ConcSm
-mkComponentInst label entity_id portassigns = AST.CSISm compins
+mkComponentInst label entity_id clockDomains portassigns = AST.CSISm compins
   where
     -- We always have a clock port, so no need to map it anywhere but here
-    clk_port = mkAssocElem clockId (idToVHDLExpr clockId)
+    clkPorts = map (\clkId -> mkAssocElem clkId (idToVHDLExpr clkId)) $ map (AST.unsafeVHDLBasicId . ("clock" ++) . show) clockDomains
     resetn_port = mkAssocElem resetId (idToVHDLExpr resetId)
-    compins = AST.CompInsSm (mkVHDLExtId label) (AST.IUEntity (AST.NSimple entity_id)) (AST.PMapAspect (portassigns ++ [clk_port,resetn_port]))
+    compins = AST.CompInsSm (mkVHDLExtId label) (AST.IUEntity (AST.NSimple entity_id)) (AST.PMapAspect (portassigns ++ clkPorts ++ [resetn_port]))
 
 -----------------------------------------------------------------------------
 -- Functions to generate VHDL Exprs
@@ -223,14 +225,11 @@
 varToUniqString ::
   CoreSyn.CoreBndr
   -> String
-varToUniqString var = (varToString var ++ varToStringUniq var ++ show (lowers $ varToStringUniq var))
-  where
-    lowers :: String -> Int
-    lowers xs = length [x | x <- xs, Char.isLower x]
+varToUniqString var = (varToString var ++ varToStringUniq var)
 
 -- Get the string version a Var's unique
 varToStringUniq :: Var.Var -> String
-varToStringUniq = show . Var.varUnique
+varToStringUniq = show . Unique.getKey . Var.varUnique
 
 -- Extracts the string version of the name
 nameToString :: Name.Name -> String
@@ -527,7 +526,7 @@
   elTyTmMaybe <- vhdlTyMaybe elHType
   case elTyTmMaybe of
     (Just elTyTm) -> do
-      let ty_id = mkVHDLExtId $ "vector-"++ (AST.fromVHDLId elTyTm) ++ "-0_to_" ++ (show len)
+      let ty_id = mkVHDLExtId $ "vector-"++ (AST.fromVHDLId elTyTm) ++ "-0_to_" ++ (show (len - 1))
       let range = AST.ConstraintIndex $ AST.IndexConstraint [AST.ToRange (AST.PrimLit "0") (AST.PrimLit $ show (len - 1))]
       let existing_uvec_ty = fmap (fmap fst) $ Map.lookup (UVecType elHType) typesMap
       case existing_uvec_ty of
diff --git a/Data/Accessor/Monad/Trans/StrictState.hs b/Data/Accessor/Monad/Trans/StrictState.hs
new file mode 100644
--- /dev/null
+++ b/Data/Accessor/Monad/Trans/StrictState.hs
@@ -0,0 +1,38 @@
+module Data.Accessor.Monad.Trans.StrictState where
+  
+import qualified Data.Accessor.Basic as Accessor
+import qualified Control.Monad.Trans.State.Strict as State
+import qualified Control.Monad.Trans.Class as Trans
+import Control.Monad.Trans.State.Strict (State, runState, StateT(runStateT), )
+
+set :: Monad m => Accessor.T r a -> a -> StateT r m ()
+set f x = State.modify (Accessor.set f x)
+
+get :: Monad m => Accessor.T r a -> StateT r m a
+get f = State.gets (Accessor.get f)
+
+modify :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m ()
+modify f g = State.modify (Accessor.modify f g)
+
+infix 1 %=, %:
+
+(%=) :: Monad m => Accessor.T r a -> a -> StateT r m ()
+(%=) = set
+
+(%:) :: Monad m => Accessor.T r a -> (a -> a) -> StateT r m ()
+(%:) = modify
+
+lift :: Monad m => Accessor.T r s -> State s a -> StateT r m a
+lift f m =
+   do s0 <- get f
+      let (a,s1) = runState m s0
+      set f s1
+      return a
+
+liftT :: (Monad m) =>
+   Accessor.T r s -> StateT s m a -> StateT r m a
+liftT f m =
+   do s0 <- get f
+      (a,s1) <- Trans.lift $ runStateT m s0
+      set f s1
+      return a
diff --git a/clash.cabal b/clash.cabal
--- a/clash.cabal
+++ b/clash.cabal
@@ -1,5 +1,5 @@
 name:               clash
-version:            0.1.2.5
+version:            0.1.3.0
 build-type:         Simple
 synopsis:           CAES Language for Synchronous Hardware (CLaSH)
 description:        CLaSH is a tool-chain/language to translate subsets of
@@ -22,8 +22,8 @@
   build-depends:    ghc >= 6.12 && < 6.13, pretty, vhdl > 0.1.1, haskell98, syb,
                     data-accessor >= 0.2.1.3, containers, base >= 4 && < 5, 
                     transformers >= 0.2, filepath, template-haskell, 
-                    data-accessor-template, data-accessor-transformers, 
-                    prettyclass, directory, tfp, th-lift, time
+                    data-accessor-template, prettyclass, directory, tfp, 
+                    th-lift, time
                     
   exposed-modules:  CLasH.HardwareTypes
                     CLasH.Translator
@@ -33,6 +33,7 @@
                     Data.Param.Unsigned
                     Data.Param.Index
                     Data.Param.Vector
+                    Data.Accessor.Monad.Trans.StrictState
                     CLasH.Translator.TranslatorTypes
                     CLasH.Translator.Annotations
                     CLasH.Normalize
