-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathSerial.hs
More file actions
94 lines (80 loc) · 2.38 KB
/
Serial.hs
File metadata and controls
94 lines (80 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
module Veldt.Serial
( Direction(..)
-- Deserializer
, Deserializer
, mkDeserializer
, full
, deserialize
, get
, clear
-- Serializer
, Serializer
, mkSerializer
, empty
, serialize
, peek
, give
) where
import Clash.Prelude hiding (empty)
import Control.Monad.RWS (RWST)
import Control.Lens hiding (Index)
import qualified Veldt.Counter as C
data Direction = L | R
deriving (NFDataX, Generic)
------------------
-- Deserializer --
------------------
data Deserializer n a = Deserializer
{ _dBuf :: Vec n a
, _dFull :: Bool
, _dCtr :: Index n
, _dDir :: Direction
} deriving (NFDataX, Generic)
makeLenses ''Deserializer
mkDeserializer :: KnownNat n => a -> Direction -> Deserializer n a
mkDeserializer a = Deserializer (repeat a) False 0
full :: (Monoid w, Monad m) => RWST r w (Deserializer n a) m Bool
full = use dFull
deserialize :: (Monoid w, Monad m, KnownNat n) => a -> RWST r w (Deserializer n a) m ()
deserialize d = do
use dDir >>= \case
R -> dBuf %= (<<+ d)
L -> dBuf %= (d +>>)
dFull <~ uses dCtr (== maxBound)
dCtr %= C.increment
get :: (Monoid w, Monad m) => RWST r w (Deserializer n a) m (Vec n a)
get = use dBuf
clear :: (Monoid w, Monad m, KnownNat n) => RWST r w (Deserializer n a) m ()
clear = do
dFull .= False
dCtr .= 0
----------------
-- Serializer --
----------------
data Serializer n a = Serializer
{ _sBuf :: Vec n a
, _sEmpty :: Bool
, _sCtr :: Index n
, _sDir :: Direction
} deriving (NFDataX, Generic)
makeLenses ''Serializer
mkSerializer :: KnownNat n => a -> Direction -> Serializer n a
mkSerializer a = Serializer (repeat a) True 0
serialize :: (Monoid w, Monad m, KnownNat n) => RWST r w (Serializer n a) m ()
serialize = do
use sDir >>= \case
R -> sBuf %= (`rotateRightS` d1)
L -> sBuf %= (`rotateLeftS` d1)
sEmpty <~ uses sCtr (== maxBound)
sCtr %= C.increment
peek :: (Monoid w, Monad m, KnownNat n) => RWST r w (Serializer (n + 1) a) m a
peek = use sDir >>= \case
R -> uses sBuf last
L -> uses sBuf head
give :: (Monoid w, Monad m, KnownNat n) => Vec n a -> RWST r w (Serializer n a) m ()
give v = do
sBuf .= v
sEmpty .= False
sCtr .= 0
empty :: (Monoid w, Monad m) => RWST r w (Serializer n a) m Bool
empty = use sEmpty