packages feed

clash-0.1.2.0: CLasH/HardwareTypes.hs

{-# LANGUAGE TemplateHaskell, DeriveDataTypeable #-}

module CLasH.HardwareTypes
  ( module Types
  , module Data.Param.Integer
  , module Data.Param.Vector
  , module Data.Param.Index
  , module Data.Param.Signed
  , module Data.Param.Unsigned
  , module Data.Bits
  , module Language.Haskell.TH.Lift
  , module Control.Category
  , module Control.Arrow
  , module Control.Monad.Fix
  , module CLasH.Translator.Annotations
  , Bit(..)
  , State(..)
  , hwand
  , hwor
  , hwxor
  , hwnot
  , RAM
  , MemState
  , blockRAM
  , Stat
  , simulate
  , (^^^)
  ) where

import Types
import Data.Param.Integer (HWBits(..))
import Data.Param.Vector
import Data.Param.Index
import Data.Param.Signed
import Data.Param.Unsigned 
import Data.Bits hiding (shiftL,shiftR)

import Language.Haskell.TH.Lift
import Data.Typeable

import Control.Category (Category,(.),id)
import Control.Arrow (Arrow,arr,first,ArrowLoop,loop,(>>>),second,returnA)
import Control.Monad.Fix (mfix)
import qualified Prelude as P
import Prelude hiding (id, (.))

import CLasH.Translator.Annotations

newtype State s = State s deriving (P.Show)

-- The plain Bit type
data Bit = High | Low
  deriving (P.Show, Eq, P.Read, Typeable)

deriveLift ''Bit

hwand :: Bit -> Bit -> Bit
hwor  :: Bit -> Bit -> Bit
hwxor :: Bit -> Bit -> Bit
hwnot :: Bit -> Bit

High `hwand` High = High
_    `hwand` _    = Low

Low  `hwor` Low   = Low
_    `hwor` _     = High

High `hwxor` Low  = High
Low  `hwxor` High = High
_    `hwxor` _    = Low

hwnot High = Low
hwnot Low  = High

type RAM s a          = Vector s a
type MemState s a     = State (RAM s a)

blockRAM :: 
  PositiveT s  =>
  MemState s a -> 
  a ->
  Index s ->
  Index s ->
  Bool -> 
  (MemState s a, a )
blockRAM (State mem) data_in rdaddr wraddr wrenable = 
  ((State mem'), data_out)
  where
    data_out  = mem!rdaddr
    -- Only write data_in to memory if write is enabled
    mem' =  if wrenable then
              vreplace mem wraddr data_in
            else
              mem

-- ==================
-- = Automata Arrow =
-- ==================
newtype Stat i o = A {
     apply :: i -> (o, Stat 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 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'))

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)

simulate :: Stat b c -> [b] -> [c]
simulate (A f) []     = []
simulate (A f) (b:bs) = let (c,f') = f b in (c : simulate f' bs)

arrState :: s -> (State s -> i -> (State s,o)) -> Stat i o
arrState = liftS

(^^^) :: (State s -> i -> (State s,o)) -> s -> Stat i o
(^^^) f init = arrState init f