X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Fhaskell-symposium-talk.git;a=blobdiff_plain;f=PolyAlu.lhs;h=a4dc6e141cce0b0f0314bfae51ce48f81be3f5ba;hp=842da238e628477a6ea9face795323e11022e38e;hb=HEAD;hpb=715d9487c4e666cef21e89f0735d23a4f5ab2d27 diff --git a/PolyAlu.lhs b/PolyAlu.lhs index 842da23..a4dc6e1 100644 --- a/PolyAlu.lhs +++ b/PolyAlu.lhs @@ -4,6 +4,8 @@ {-# LANGUAGE TypeOperators, TypeFamilies, FlexibleContexts #-} module Main where +import CLasH.HardwareTypes +import CLasH.Translator.Annotations import qualified Prelude as P \end{code} %endif @@ -12,12 +14,19 @@ import qualified Prelude as P \subsection{Introduction} \frame { -\frametitle{Small Use Case}\pause +\frametitle{Small Use Case} +\begin{columns}[l] +\column{0.5\textwidth} +\begin{figure} +\includegraphics[width=4.75cm]{simpleCPU} +\end{figure} +\column{0.5\textwidth} +\vspace{5em} \begin{itemize} - \item Small Polymorphic, Higher-Order CPU\pause - \item Each function is turned into a hardware component\pause + \item Polymorphic, Higher-Order CPU \item Use of state will be simple \end{itemize} +\end{columns} }\note[itemize]{ \item Small "toy"-example of what can be done in \clash{} \item Show what can be translated to Hardware @@ -25,107 +34,67 @@ import qualified Prelude as P \item Use of state will be kept simple } -\frame -{ -\frametitle{Imports}\pause -Import all the built-in types, such as vectors and integers: -\begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} -\begin{code} -import CLasH.HardwareTypes -\end{code} -\end{beamercolorbox}\pause - -Import annotations, helps \clash{} to find top-level component: -\begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} -\begin{code} -import CLasH.Translator.Annotations -\end{code} -\end{beamercolorbox} -}\note[itemize]{ -\item The first input is always needed, as it contains the builtin types -\item The second one is only needed if you want to make use of Annotations -} - \subsection{Type Definitions} \frame { \frametitle{Type definitions}\pause +\begin{columns}[l] +\column{0.5\textwidth} +\begin{figure} +\includegraphics[width=4.75cm]{simpleCPU} +\end{figure} +\column{0.5\textwidth} +\vspace{2em} + First we define some ALU types: \begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} \begin{code} -type Op s a = a -> Vector s a -> a -type Opcode = Bit +type Op a = a -> a -> a +type Opcode = Bit \end{code} \end{beamercolorbox}\pause - +\vspace{1em} And some Register types: \begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} \begin{code} -type RegBank s a = Vector (s :+: D1) a -type RegState s a = State (RegBank s a) -\end{code} -\end{beamercolorbox}\pause - -And a simple Word type: -\begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} -\begin{code} -type Word = SizedInt D12 +type RegBank s a = + Vector (s :+: D1) a +type RegState s a = + State (RegBank s a) \end{code} \end{beamercolorbox} -}\note[itemize]{ -\item The first type is already polymorphic, both in size, and element type -\item It's a small example, so Opcode is just a Bit -\item State has to be of the State type to be recognized as such -\item SizedInt D12: One concrete type for now, to make the signatures smaller -} - -\subsection{Frameworks for Operations} -\frame -{ -\frametitle{Operations}\pause -We make a primitive operation: -\begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} -\begin{code} -primOp :: {-"{\color<4>[rgb]{1,0,0}"-}(a -> a -> a){-"}"-} -> Op s a -primOp f a b = a `f` a -\end{code} -\end{beamercolorbox}\pause - -We make a vector operation: -\begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} +%if style == newcode \begin{code} -vectOp :: {-"{\color<4>[rgb]{1,0,0}"-}(a -> a -> a){-"}"-} -> Op s a -vectOp f a b = {-"{\color<4>[rgb]{1,0,0}"-}foldl{-"}"-} f a b +type Word = SizedInt D12 \end{code} -\end{beamercolorbox} -\begin{itemize} -\uncover<4->{\item We support Higher-Order Functionality} -\end{itemize} +%endif +\end{columns} }\note[itemize]{ -\item These are just frameworks for 'real' operations -\item Notice how they are High-Order functions +\item The ALU operation is already polymorphic in input / output type +\item We use a fixed size vector as the placeholder for the registers +\item State has to be of the State type to be recognized as such } \subsection{Polymorphic, Higher-Order ALU} \frame { \frametitle{Simple ALU} -We define a polymorphic ALU: +\begin{figure} +\includegraphics[width=5.25cm,trim=0mm 5.5cm 0mm 1cm, clip=true]{simpleCPU} +\end{figure} +Abstract ALU definition: \begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} \begin{code} alu :: - Op s a -> - Op s a -> - Opcode -> a -> Vector s a -> a + Op a -> Op a -> + Opcode -> a -> a -> a alu op1 op2 {-"{\color<2>[rgb]{1,0,0}"-}Low{-"}"-} a b = op1 a b alu op1 op2 {-"{\color<2>[rgb]{1,0,0}"-}High{-"}"-} a b = op2 a b \end{code} \end{beamercolorbox} -\begin{itemize} -\uncover<2->{\item We support Patter Matching} -\end{itemize} }\note[itemize]{ \item Alu is both higher-order, and polymorphic +\item First two parameters are "compile time", other three are "runtime" \item We support pattern matching } @@ -133,28 +102,29 @@ alu op1 op2 {-"{\color<2>[rgb]{1,0,0}"-}High{-"}"-} a b = op2 a b \frame { \frametitle{Register Bank} -Make a simple register bank: +\begin{figure} +\includegraphics[width=5.25cm,trim=0mm 0.4cm 0mm 6.2cm, clip=true]{simpleCPU} +\end{figure} +%if style == newcode +\begin{code} +registers :: + CXT((NaturalT s ,PositiveT (s :+: D1),((s :+: D1) :>: s) ~ True )) => a -> RangedWord s -> + RangedWord s -> (RegState s a) -> (RegState s a, a ) +\end{code} +%endif +A simple register bank: \begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} \begin{code} -registerBank :: - CXT((NaturalT s ,PositiveT (s :+: D1),((s :+: D1) :>: s) ~ True )) => (RegState s a) -> a -> RangedWord s -> - RangedWord s -> Bit -> ((RegState s a), a ) - -registerBank (State mem) data_in rdaddr wraddr wrenable = +registers data_in rdaddr wraddr (State mem) = ((State mem'), data_out) where - data_out = mem!rdaddr - mem' {-"{\color<2>[rgb]{1,0,0}"-}| wrenable == Low{-"}"-} = mem - {-"{\color<2>[rgb]{1,0,0}"-}| otherwise{-"}"-} = replace mem wraddr data_in + data_out = mem!rdaddr + mem' = replace mem wraddr data_in \end{code} \end{beamercolorbox} -\begin{itemize} -\uncover<2->{\item We support Guards} -\end{itemize} }\note[itemize]{ -\item RangedWord runs from 0 to the upper bound -\item mem is statefull -\item We support guards +\item mem is statefull, indicated by the 'State' type +\item replace and (!) are a builtin functions } \subsection{Simple CPU: ALU \& Register Bank} @@ -163,25 +133,29 @@ registerBank (State mem) data_in rdaddr wraddr wrenable = \frametitle{Simple CPU} Combining ALU and register bank: \begin{beamercolorbox}[sep=-2.5ex,rounded=true,shadow=true,vmode]{codebox} +%if style == newcode \begin{code} -{-"{\color<2>[rgb]{1,0,0}"-}ANN(actual_cpu TopEntity){-"}"-} -actual_cpu :: - (Opcode, Word, Vector D4 Word, RangedWord D9, - RangedWord D9, Bit) -> RegState D9 Word -> - (RegState D9 Word, Word) +type Instruction = (Opcode, Word, RangedWord D9, RangedWord D9) +\end{code} +%endif +\begin{code} +{-"{\color<2>[rgb]{1,0,0}"-}ANN(cpu TopEntity){-"}"-} +cpu :: + Instruction -> RegState D9 Word -> (RegState D9 Word, Word) -actual_cpu (opc, a ,b, rdaddr, wraddr, wren) ram = (ram', alu_out) +cpu (opc, d, rdaddr, wraddr) ram = (ram', alu_out) where - alu_out = alu ({-"{\color<3>[rgb]{1,0,0}"-}primOp (+){-"}"-}) ({-"{\color<3>[rgb]{1,0,0}"-}vectOp (+){-"}"-}) opc ram_out b - (ram',ram_out) = registerBank ram a rdaddr wraddr wren + alu_out = alu {-"{\color<3>[rgb]{1,0,0}"-}(+){-"}"-} {-"{\color<3>[rgb]{1,0,0}"-}(-){-"}"-} opc d ram_out + (ram',ram_out) = registers alu_out rdaddr wraddr ram \end{code} \end{beamercolorbox} \begin{itemize} \uncover<2->{\item Annotation is used to indicate top-level component} +\uncover<3->{\item Instantiate actual operations} \end{itemize} }\note[itemize]{ -\item We use the new Annotion functionality to indicate this is the top level -\item the primOp and vectOp frameworks are now supplied with real functionality, the plus (+) operations +\item We use the new Annotion functionality to indicate this is the top level. TopEntity is defined by us. +\item At this stage, both operations for the ALU are defined \item No polymorphism or higher-order stuff is allowed at this level. \item Functions must be specialized, and have primitives for input and output } @@ -193,11 +167,11 @@ initstate :: RegState D9 Word initstate = State (copy (0 :: Word)) ANN(program TestInput) -program :: [(Opcode, Word, Vector D4 Word, RangedWord D9, RangedWord D9, Bit)] +program :: [Instruction] program = - [ (Low, 4, copy (0::Word), 0, 0, High) -- Write 4 to Reg0, out = 0 - , (Low, 3, copy (0::Word), 0, 1, High) -- Write 3 to Reg1, out = Reg0 + Reg0 = 8 - , (High,0, copy (3::Word), 1, 0, Low) -- No Write , out = 15 + [ (Low, 4, 0, 0) -- Write 4 to Reg0 + , (Low, 3, 0, 1) -- Write 3+4 to Reg1 + , (High,8, 1, 2) -- Write 8-7 to Reg2 ] run func state [] = [] @@ -210,8 +184,8 @@ main :: IO () main = do let input = program let istate = initstate - let output = run actual_cpu istate input + let output = run cpu istate input mapM_ (\x -> putStr $ ("(" P.++ (show x) P.++ ")\n")) output return () \end{code} -%endif \ No newline at end of file +%endif