Initial import
[matthijs/master-project/haskell-symposium-talk.git] / PolyAlu.lhs
1 %include talk.fmt
2 %if style == newcode
3 \begin{code}
4 {-# LANGUAGE  TypeOperators, TypeFamilies, FlexibleContexts #-}
5 module PolyCPU where
6
7 import qualified Prelude as P
8 \end{code}
9 %endif
10
11 \section{Polymorphic, Higher-Order CPU}
12 \subsection{Introduction}
13 \frame
14 {
15 \frametitle{Small Use Case}
16 \begin{itemize}
17   \item Small Polymorphic, Higher-Order CPU
18   \item Each function is turned into a hardware component
19   \item Use of state will be simple
20 \end{itemize}
21 }
22
23 \frame
24 {
25 \frametitle{Imports}
26 \begin{code}
27 import {-"{\color<2>[rgb]{1,0,0}"-}CLasH.HardwareTypes{-"}"-}
28 import {-"{\color<3>[rgb]{1,0,0}"-}CLasH.Translator.Annotations{-"}"-}
29 \end{code}
30 }
31
32 \subsection{Type Definitions}
33 \frame
34 {
35 First we define some ALU types:
36 \begin{code}
37 type Op s a         =   a -> {-"{\color<2>[rgb]{1,0,0}"-}Vector s a{-"}"-} -> a
38 type Opcode         =   Bit
39 \end{code}
40 And some Register types:
41 \begin{code}
42 type RegBank s a    =   {-"{\color<2>[rgb]{1,0,0}"-}Vector (s :+: D1){-"}"-} a
43 type RegState s a   =   State (RegBank s a)
44 \end{code}
45 And a simple Word type:
46 \begin{code}
47 type Word           =   {-"{\color<3>[rgb]{1,0,0}"-}SizedInt D12{-"}"-}
48 \end{code}
49 }
50 \subsection{Frameworks for Operations}
51 \frame
52 {
53 We make a primitive operation:
54 \begin{code}
55 primOp :: {-"{\color<2>[rgb]{1,0,0}"-}(a -> a -> a){-"}"-} -> Op s a
56 primOp f a b = a `f` a
57 \end{code}
58 We make a vector operation:
59 \begin{code}
60 vectOp :: {-"{\color<2>[rgb]{1,0,0}"-}(a -> a -> a){-"}"-} -> Op s a
61 vectOp f a b = {-"{\color<2>[rgb]{1,0,0}"-}foldl{-"}"-} f a b
62 \end{code}
63 }
64 \subsection{Polymorphic, Higher-Order ALU}
65 \frame
66 {
67 We define a polymorphic ALU:
68 \begin{code}
69 alu :: 
70   Op s a -> 
71   Op s a -> 
72   Opcode -> a -> Vector s a -> a
73 alu op1 op2 {-"{\color<2>[rgb]{1,0,0}"-}Low{-"}"-}    a b = op1 a b
74 alu op1 op2 {-"{\color<2>[rgb]{1,0,0}"-}High{-"}"-}   a b = op2 a b
75 \end{code}
76 }
77 \subsection{Register bank}
78 \frame
79 {
80 Make a simple register bank:
81 \begin{code}
82 registerBank :: 
83   CXT((NaturalT s ,PositiveT (s :+: D1),((s :+: D1) :>: s) ~ True )) =>
84   (RegState s a) -> a -> {-"{\color<2>[rgb]{1,0,0}"-}RangedWord s{-"}"-} ->
85   {-"{\color<2>[rgb]{1,0,0}"-}RangedWord s{-"}"-} -> Bit -> ((RegState s a), a )
86   
87 registerBank (State mem) data_in rdaddr wraddr wrenable = 
88   ((State mem'), data_out)
89   where
90     data_out  =   mem!rdaddr
91     mem'          {-"{\color<3>[rgb]{1,0,0}"-}| wrenable == Low{-"}"-}  = mem
92                   {-"{\color<3>[rgb]{1,0,0}"-}| otherwise{-"}"-}        = replace mem wraddr data_in
93 \end{code}
94 }
95 \subsection{Simple CPU: ALU \& Register Bank}
96 \frame
97 {
98 Combining ALU and register bank:
99 \begin{code}
100 {-"{\color<2>[rgb]{1,0,0}"-}ANN(actual_cpu TopEntity){-"}"-}
101 actual_cpu :: 
102   (Opcode, Word, Vector D4 Word, 
103   RangedWord D9, 
104   RangedWord D9, Bit) -> 
105   RegState D9 Word ->
106   (RegState D9 Word, Word)
107
108 actual_cpu (opc, a ,b, rdaddr, wraddr, wren) ram = (ram', alu_out)
109   where
110     alu_out = alu simpleOp vectorOp opc ram_out b
111     (ram',ram_out)  = registerBank ram a rdaddr wraddr wren
112     simpleOp =  primOp  (+)
113     vectorOp =  vectOp  (+)
114 \end{code}
115 }