X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Fdsd-paper.git;a=blobdiff_plain;f=c%CE%BBash.lhs;h=8452e4bd423815a66d64bfaf9530f3735276ef72;hp=4c36e8fc0dfbfc7f8ba84ebdbcaf05428be989f1;hb=8905eead137ece683eaac04b4f7ab6711909a123;hpb=c1c6081ec7a5c09f9becd1faf332dbc746f50c94 diff --git "a/c\316\273ash.lhs" "b/c\316\273ash.lhs" index 4c36e8f..8452e4b 100644 --- "a/c\316\273ash.lhs" +++ "b/c\316\273ash.lhs" @@ -342,9 +342,11 @@ % Macro for certain acronyms in small caps. Doesn't work with the % default font, though (it contains no smallcaps it seems). \def\acro#1{{\small{#1}}} +\def\acrotiny#1{{\scriptsize{#1}}} \def\VHDL{\acro{VHDL}} \def\GHC{\acro{GHC}} \def\CLaSH{{\small{C}}$\lambda$a{\small{SH}}} +\def\CLaSHtiny{{\scriptsize{C}}$\lambda$a{\scriptsize{SH}}} % Macro for pretty printing haskell snippets. Just monospaced for now, perhaps % we'll get something more complex later on. @@ -526,22 +528,23 @@ optimizing Haskell compiler such as the Glasgow Haskell Compiler (\GHC)~\cite{gh Where descriptions in a conventional hardware description language have an explicit clock for the purpose state and synchronicity, the clock is implied in this research. A developer describes the behavior of the hardware between -clock cycles. The current abstraction of state and time limits the -descriptions to synchronous hardware, there however is room within the -language to eventually add a different abstraction mechanism that will allow -for the modeling of asynchronous systems. Many functional hardware description -model signals as a stream of all values over time; state is then modeled as a -delay on this stream of values. The approach taken in this research is to make -the current state of a circuit part of the input of the function and the -updated state part of the output. +clock cycles. Many functional hardware description model signals as a stream +of all values over time; state is then modeled as a delay on this stream of +values. The approach taken in this research is to make the current state of a +circuit part of the input of the function and the updated state part of the +output. The current abstraction of state and time limits the descriptions to +synchronous hardware, there however is room within the language to eventually +add a different abstraction mechanism that will allow for the modeling of +asynchronous systems. Like the standard hardware description languages, descriptions made in a functional hardware description language must eventually be converted into a netlist. This research also features a prototype translator, which has the -same name as the language: \CLaSH\footnote{C$\lambda$aSH: CAES Language for -Synchronous Hardware} (pronounced: clash). This compiler converts the Haskell -code to equivalently behaving synthesizable \VHDL\ code, ready to be converted -to an actual netlist format by an (optimizing) \VHDL\ synthesis tool. +same name as the language: \CLaSH\footnote{\CLaSHtiny: \acrotiny{CAES} +Language for Synchronous Hardware} (pronounced: clash). This compiler converts +the Haskell code to equivalently behaving synthesizable \VHDL\ code, ready to +be converted to an actual netlist format by an (optimizing) \VHDL\ synthesis +tool. Besides trivial circuits such as variants of both the FIR filter and the simple CPU shown in \Cref{sec:usecases}, the \CLaSH\ compiler has also been @@ -562,8 +565,8 @@ circuit~\cite{reductioncircuit} for floating point numbers. and \item function applications are translated to component instantiations. \end{inparaenum} - The output port can have a complex type (such as a tuple), so having just - a single output port does not pose any limitation. The arguments of a + The output port can have a structured type (such as a tuple), so having + just a single output port does not pose any limitation. The arguments of a function application are assigned to signals, which are then mapped to the corresponding input ports of the component. The output port of the function is also mapped to a signal, which is used as the result of the @@ -571,9 +574,10 @@ circuit~\cite{reductioncircuit} for floating point numbers. Since every top level function generates its own component, the hierarchy of function calls is reflected in the final netlist,% aswell, - creating a hierarchical description of the hardware. This separation in - different components makes the resulting \VHDL\ output easier to read and - debug. + creating a hierarchical description of the hardware. The separation in + different components makes it easier for a developer to understand and + possibly hand-optimize the resulting \VHDL\ output of the \CLaSH\ + compiler. As an example we can see the netlist of the |mac| function in \Cref{img:mac-comb}; the |mac| function applies both the |mul| and |add| @@ -589,7 +593,7 @@ circuit~\cite{reductioncircuit} for floating point numbers. \label{img:mac-comb} \end{figure} - The result of using a complex input type can be seen in + The result of using a structural input type can be seen in \cref{img:mac-comb-nocurry} where the |mac| function now uses a single input tuple for the |a|, |b|, and |c| arguments: @@ -606,7 +610,7 @@ circuit~\cite{reductioncircuit} for floating point numbers. \subsection{Choice} In Haskell, choice can be achieved by a large set of language constructs, consisting of: \hs{case} constructs, \hs{if-then-else} constructs, - pattern matching, and guards. The easiest of these are the \hs{case} + pattern matching, and guards. The most general of these are the \hs{case} constructs (\hs{if} expressions can be very directly translated to \hs{case} expressions). A \hs{case} construct is translated to a multiplexer, where the control value is linked to the selection port and @@ -616,17 +620,27 @@ circuit~\cite{reductioncircuit} for floating point numbers. % assignment in \VHDL, where the conditions use equality comparisons % against the constructors in the \hs{case} expressions. We can see two versions of a contrived example below, the first - using a \hs{case} construct and the other using a \hs{if-then-else} - constructs, in the code below. + using a \hs{case} construct and the other using an \hs{if-then-else} + construct, in the code below. The examples sums two values when they are + equal or non-equal (depending on the given predicate, the \hs{pred} + variable) and returns 0 otherwise. The \hs{pred} variable has the + following, user-defined, enumeration datatype: \begin{code} + data Pred = Equiv | NotEquiv + \end{code} + + The naive netlist corresponding to both versions of the example is + depicted in \Cref{img:choice}. + + \begin{code} sumif pred a b = case pred of - Eq -> case a == b of - True -> a + b - False -> 0 - Neq -> case a != b of - True -> a + b - False -> 0 + Equiv -> case a == b of + True -> a + b + False -> 0 + NotEquiv -> case a != b of + True -> a + b + False -> 0 \end{code} \begin{code} @@ -642,23 +656,24 @@ circuit~\cite{reductioncircuit} for floating point numbers. \caption{Choice - sumif} \label{img:choice} \end{figure} - - The example sums two values when they are equal or non-equal (depending on - the predicate given) and returns 0 otherwise. Both versions of the example - roughly correspond to the same netlist, which is depicted in - \Cref{img:choice}. - A slightly more complex (but very powerful) form of choice is pattern + A user-friendly and also very powerful form of choice is pattern matching. A function can be defined in multiple clauses, where each clause - specifies a pattern. When the arguments match the pattern, the + corresponds to a pattern. When an argument matches a pattern, the corresponding clause will be used. Expressions can also contain guards, - where the expression is only executed if the guard evaluates to true. Like + where the expression is only executed if the guard evaluates to true, and + continues with the next clause if the guard evaluates to false. Like \hs{if-then-else} constructs, pattern matching and guards have a (straightforward) translation to \hs{case} constructs and can as such be mapped to multiplexers. A third version of the earlier example, using both - pattern matching and guards, can be seen below. The version using pattern - matching and guards also has roughly the same netlist representation - (\Cref{img:choice}) as the earlier two versions of the example. + pattern matching and guards, can be seen below. The guard is the + expression that follows the vertical bar (\hs{|}) and precedes the + assignment operator (\hs{=}). The \hs{otherwise} guards always evaluate to + \hs{true}. + + The version using pattern matching and guards corresponds to the same + naive netlist representation (\Cref{img:choice}) as the earlier two + versions of the example. \begin{code} sumif Eq a b | a == b = a + b @@ -1032,7 +1047,7 @@ hardware. \begin{figure} \centerline{\includegraphics{compilerpipeline.svg}} -\caption{\CLaSH\ compiler pipeline} +\caption{\CLaSHtiny\ compiler pipeline} \label{img:compilerpipeline} \end{figure} @@ -1127,7 +1142,7 @@ is depicted in \Cref{img:4tapfir}. \begin{figure} \centerline{\includegraphics{4tapfir.svg}} -\caption{4-taps FIR Filter} +\caption{4-taps \acrotiny{FIR} Filter} \label{img:4tapfir} \end{figure}