root/hhdl/problem.hs

Revision 44, 10.0 kB (checked in by thesz, 1 year ago)

Added separate Entities.hs where I will put various entities that cannot be expressed purely in HHDL.

  • Property svn:executable set to *
Line 
1 -- "A problem with functional dependencies.
2 -- use -fcontext-stack=100 ghc switch.
3
4 {-# LANGUAGE GADTs, FunctionalDependencies, MultiParamTypeClasses, TypeSynonymInstances, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}
5
6 module Problem where
7
8 import Data.Bits
9 import Data.Word
10
11 -------------------------------------------------------------------------------
12 -- Type level arithmetic.
13
14 data Zero = Zero
15 data Succ n = Succ n
16
17 type ZERO = Zero
18 type ONE = Succ ZERO
19 type TWO = Succ ONE
20 type THREE = Succ TWO
21 type FOUR = Succ THREE
22 type FIVE = Succ FOUR
23 type SIX = Succ FIVE
24 type SEVEN = Succ SIX
25 type EIGHT = Succ SEVEN
26 type NINE = Succ EIGHT
27 type SIZE10 = Succ NINE
28 type SIZE11 = Succ SIZE10
29 type SIZE12 = Succ SIZE11
30 type SIZE13 = Succ SIZE12
31 type SIZE15 = Succ (Succ SIZE13)
32 type SIZE16 = Succ SIZE15
33 type SIZE20 = Succ (Succ (Succ (Succ (Succ SIZE15))))
34 type SIZE25 = Succ (Succ (Succ (Succ (Succ SIZE20))))
35 type SIZE26 = Succ SIZE25
36 type SIZE30 = Succ (Succ (Succ (Succ (Succ SIZE25))))
37 type SIZE32 = Succ (Succ SIZE30)
38
39 class Nat n where fromNat :: n -> Int
40
41 instance Nat Zero where fromNat = const 0
42 instance Nat n => Nat (Succ n) where fromNat ~(Succ n) = 1+fromNat n
43
44 class (Nat a, Nat b, Nat c) => CPlus a b c | a b -> c, a c -> b
45
46 --instance Nat a => CPlus a Zero a
47 instance Nat a => CPlus Zero a a
48 instance (CPlus a b c) => CPlus (Succ a) b (Succ c)
49 --instance (CPlus a b c) => CPlus (Succ a) b (Succ c)
50 --instance (CPlus a b c) => CPlus a (Succ b) (Succ c)
51
52 class (Nat a, Nat b, Nat c) => CMax a b c | a b -> c
53 instance CMax Zero Zero Zero
54 instance Nat a => CMax (Succ a) Zero (Succ a)
55 instance Nat a => CMax Zero (Succ a) (Succ a)
56 instance CMax a b c => CMax (Succ a) (Succ b) (Succ c)
57
58 class (Nat a, Nat b) => CDbl a b | a -> b
59 instance CPlus a a b => CDbl a b
60
61 class (Nat a, Nat b) => CPow2 a b | a -> b
62 instance CPow2 Zero (Succ Zero)
63 instance (CPow2 a b, CDbl b b2) => CPow2 (Succ a) b2
64
65 -------------------------------------------------------------------------------
66 -- Sized integer.
67
68 data IntSz n where
69         IntSz :: Nat sz => Integer -> IntSz sz
70
71 intSzSizeType :: IntSz n -> n; intSzSizeType _ = undefined
72 intSzSize :: Nat n => IntSz n -> Int; intSzSize n = fromNat $ intSzSizeType n
73
74 instance Nat sz => Eq (IntSz sz) where
75         (IntSz a) == (IntSz b) = a == b
76
77 instance Show (IntSz n) where
78         show n@(IntSz x) = show x++"{"++show (intSzSize n)++"}"
79
80 instance Nat sz => Num (IntSz sz) where
81         fromInteger x = IntSz x
82         (IntSz a) + (IntSz b) = IntSz $ a+b
83         (IntSz a) - (IntSz b) = IntSz $ a-b
84         (IntSz a) * (IntSz b) = IntSz $ a*b
85         abs = error "No abs for IntSz."
86         signum = error "No signum for IntSz."
87
88 -------------------------------------------------------------------------------
89 -- ToWires class, the main source of problems.
90
91 class Nat aSz => ToWires a aSz | a -> aSz where
92         wireSizeType :: a -> aSz
93         wireSizeType _ = undefined
94         wireSize :: a -> Int
95         wireSize x = fromNat $ wireSizeType x
96         wireMul :: a -> Integer
97         wireMul x = Data.Bits.shiftL 1 (wireSize x)
98         wireSelSize :: a -> Int
99         wireSelSize = const 0
100         -- Integer should occupy no more than wireSize bits, higher ones should 0
101         toWires :: a -> Integer
102         -- fromWires should work with integers that have non-zero bits
103         -- above wireSize index.
104         fromWires :: Integer -> a
105         -- enumeration.
106         -- valuesCount of (Maybe a) returns 1+valuesCount (x::a)
107         -- valuesCount of Either a b returns valuesCount (x::a) + valuesCount (yLLb)
108         -- valuesCount of (a,b) returns valuesCoutn (x::a) * valuesCount (y::b)
109         valuesCount :: a -> Integer
110         -- valueIndex.
111         -- get a value and return an index inside enumeration.
112         valueIndex :: a -> Integer
113
114 -------------------------------------------------------------------------------
115 -- Instances.
116
117 instance (ToWires x a,ToWires y b, CPlus a b c) => ToWires (x,y) c where
118         toWires (a,b) = Data.Bits.shiftL (toWires a) (wireSize b) .|. toWires b
119         fromWires x = (a,b)
120                 where
121                         b = fromWires x
122                         a = fromWires $ Data.Bits.shiftR x (wireSize b)
123         valuesCount (a,b) = valuesCount a*valuesCount b
124         valueIndex (a,b) = valueIndex a*valuesCount b + valueIndex b
125
126 instance (ToWires x1 a,ToWires x2 b,ToWires x3 c,
127         CPlus b c bc, CPlus a bc abc) =>
128         ToWires (x1,x2,x3) abc where
129         toWires (a,b,c) = toWires (a,(b,c))
130         fromWires abc = (a,b,c)
131                 where
132                         (a,(b,c)) = fromWires abc
133         valuesCount (a,b,c) = valuesCount (a,(b,c))
134         valueIndex (a,b,c) = valueIndex (a,(b,c))
135
136 instance (ToWires x1 a,ToWires x2 b,ToWires x3 c,ToWires x4 d,ToWires x5 e,
137         CPlus d e de, CPlus c de cde, CPlus b cde bcde, CPlus a bcde abcde) =>
138         ToWires (x1,x2,x3,x4,x5) abcde where
139         toWires (a,b,c,d,e) = toWires (a,(b,(c,(d,e))))
140         fromWires abcde = (a,b,c,d,e)
141                 where
142                         (a,(b,(c,(d,e)))) = fromWires abcde
143         valuesCount (a,b,c,d,e) = valuesCount (a,(b,(c,(d,e))))
144         valueIndex (a,b,c,d,e) = valueIndex (a,(b,(c,(d,e))))
145
146 instance CPow2 FIVE size32 => ToWires Int size32 where
147         toWires n = fromIntegral n .&. 0xffffffff
148         fromWires x = fromIntegral x
149         valuesCount = const (Data.Bits.shiftL (1::Integer) 32)
150         valueIndex = fromIntegral
151
152 instance CPow2 FIVE size32 => ToWires Word32 size32 where
153         toWires n = fromIntegral n .&. 0xffffffff
154         fromWires x = fromIntegral x
155         valuesCount = const (Data.Bits.shiftL (1::Integer) 32)
156         valueIndex = fromIntegral
157
158 instance Nat size => ToWires (IntSz size) size where
159         toWires x@(IntSz n) = n .&. (Data.Bits.shiftL 1 (wireSize x) - 1)
160         fromWires x = fromIntegral x
161         valuesCount x = Data.Bits.shiftL (1::Integer) (wireSize x)
162         valueIndex x = toWires x
163
164 -------------------------------------------------------------------------------
165 -- Types for a problem.
166
167 -- A hack around bugs (??) in ghc 6.10.1.
168 data RI = RI (IntSz FIVE)
169         deriving (Eq,Show)
170 data Imm5 = Imm5 (IntSz FIVE)
171         deriving (Eq,Show)
172 data Imm16 = Imm16 (IntSz SIZE16)
173         deriving (Eq,Show)
174 data Imm26 = Imm26 (IntSz SIZE26)
175         deriving (Eq,Show)
176
177 instance ToWires RI FIVE where
178         toWires (RI x) = toWires x
179         fromWires x = RI $ fromWires x
180         valuesCount = const 32
181         valueIndex (RI x) = toWires x
182
183 instance ToWires Imm5 FIVE where
184         toWires (Imm5 x) = toWires x
185         fromWires x = Imm5 $ fromWires x
186         valuesCount = const 32
187         valueIndex (Imm5 x) = toWires x
188
189 instance ToWires Imm16 SIZE16 where
190         toWires (Imm16 x) = toWires x
191         fromWires x = Imm16 $ fromWires x
192         valuesCount (Imm16 x) = valuesCount x
193         valueIndex (Imm16 x) = valueIndex x
194
195 instance ToWires Imm26 SIZE26 where
196         toWires (Imm26 x) = toWires x
197         fromWires x = Imm26 $ fromWires x
198         valuesCount (Imm26 x) = valuesCount x
199         valueIndex (Imm26 x) = toWires x
200
201 instance ToWires a sz => ToWires (Maybe a) (Succ sz) where
202         toWires Nothing = 0
203         toWires (Just x) = shiftL (toWires x) 1 .|. 1
204         fromWires = undefined
205         valuesCount x = 1+valuesCount y
206                 where
207                         ~(Just y) = x
208
209         valueIndex Nothing = 0
210         valueIndex (Just x) = 1+valueIndex x
211
212 -------------------------------------------------------------------------------
213 -- And a problem itself.
214
215 data Signed = Signed | Unsigned
216         deriving (Eq,Show)
217
218 data MIPSCmd regv =
219                 Nop
220         |       Trap
221         -- we mark destination register with RI. It never gets fetched.
222         -- we mark source registers as regv, because they can change their size
223         -- at FETCH stage (became Word32).
224         |       AddU    regv regv RI
225         |       And     regv regv RI
226         |       Div     Signed regv regv
227         deriving (Eq,Show)
228
229 instance ToWires Signed (Succ Zero) where
230         toWires (Signed) = Data.Bits.shiftL 0 1 .|. 0
231         toWires (Unsigned) = Data.Bits.shiftL 0 1 .|. 1
232         fromWires x = undefined
233         valuesCount x = 1 + (1 + 0)
234                 where
235                         ~(Signed) = x
236                         ~(Unsigned) = x
237         valueIndex x = case x of
238                 Signed -> 0 + 0
239                 Unsigned -> (0 + 0) + 0
240                 where
241                         ~(Signed) = x
242                         ~(Unsigned) = x
243
244 instance (ToWires regv_0 v_1, ToWires RI v_2,
245         CPlus v_1 v_1 vCPlus_3, CPlus vCPlus_3 v_2 vCPlus_4,
246         CPlus v_1 v_1 vCPlus_5, CPlus vCPlus_5 v_2 vCPlus_6,
247         ToWires Signed v_7, CPlus v_7 v_1 vCPlus_8, CPlus vCPlus_8 v_1 vCPlus_9,
248         CMax vCPlus_4 vCPlus_6 vCMax_10, CMax vCMax_10 vCPlus_9 vCMax_11)
249         => ToWires (MIPSCmd regv_0) (Succ (Succ (Succ vCMax_11))) where
250
251         toWires (Nop) = Data.Bits.shiftL 0 3 .|. 0
252         toWires (Trap) = Data.Bits.shiftL 0 3 .|. 1
253         toWires (AddU a_12 a_13 a_14) =
254                 Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL 0 (wireSize a_12) .|. toWires a_12) (wireSize a_13) .|. toWires a_13) (wireSize a_14) .|. toWires a_14) 3 .|. 2
255         toWires (And a_15 a_16 a_17) =
256                 Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL 0 (wireSize a_15) .|. toWires a_15) (wireSize a_16) .|. toWires a_16) (wireSize a_17) .|. toWires a_17) 3 .|. 3
257         toWires (Div a_18 a_19 a_20) =
258                 Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL (Data.Bits.shiftL 0 (wireSize a_18) .|. toWires a_18) (wireSize a_19) .|. toWires a_19) (wireSize a_20) .|. toWires a_20) 3 .|. 4
259         fromWires x = undefined
260         valuesCount x = 1 + (1 + ((valuesCount x_21 * (valuesCount x_22 * (valuesCount x_23 * 1))) + ((valuesCount x_24 * (valuesCount x_25 * (valuesCount x_26 * 1))) + ((valuesCount x_27 * (valuesCount x_28 * (valuesCount x_29 * 1))) + 0))))
261                 where
262                         ~(Nop) = x
263                         ~(Trap) = x
264                         ~(AddU x_21 x_22 x_23) = x
265                         ~(And x_24 x_25 x_26) = x
266                         ~(Div x_27 x_28 x_29) = x
267         valueIndex x = case x of
268                 Nop -> 0 + 0
269                 Trap -> (0 + 0) + 0
270 -- THE PROBLEM!!!
271                 AddU ax_30 ax_31 ax_32 ->
272                         ((0 + 0) + 0) + valueIndex (ax_32,(ax_30, ax_31))
273 -- /THE PROBLEM!!!
274 {-
275                                  And x_33 x_34 x_35 -> (((0 + 0) + 0) + valuesCount (x_32,
276                                                                                      (x_30,
277                                                                                       x_31))) + valueIndex (x_35,
278                                                                                                             (x_33,
279                                                                                                              x_34))
280 -}
281                 Div x_36 x_37 x_38 -> ((((0 + 0) + 0) + valuesCount (x_32,(x_30,x_31))) + valuesCount (x_35,(x_33,x_34))) +
282                         -- valueIndex (x_38,(x_36,x_37))
283                         valueIndex x_38*valuesCount x_36*valuesCount x_37 + valueIndex x_36 * valuesCount x_37+valueIndex x_37
284                              where ~(Nop) = x
285                                    ~(Trap) = x
286                                    ~(AddU x_30 x_31 x_32) = x
287                                    ~(And x_33 x_34 x_35) = x
288                                    ~(Div x_36 x_37 x_38) = x
Note: See TracBrowser for help on using the browser.