\newcommand{\fref}[1]{\cref{#1}}
\newcommand{\Fref}[1]{\Cref{#1}}
+\usepackage{epstopdf}
+
+\epstopdfDeclareGraphicsRule{.svg}{pdf}{.pdf}{rsvg-convert --format=pdf < #1 > \noexpand\OutputFile}
%include polycode.fmt
%include clash.fmt
% author names and affiliations
% use a multiple column layout for up to three different
% affiliations
-\author{\IEEEauthorblockN{Christiaan P.R. Baaij, Matthijs Kooijman, Jan Kuper, Marco E.T. Gerards, Bert Molenkamp, Sabih H. Gerez}
-\IEEEauthorblockA{University of Twente, Department of EEMCS\\
+\author{\IEEEauthorblockN{Christiaan P.R. Baaij, Matthijs Kooijman, Jan Kuper, Marco E.T. Gerards}%, Bert Molenkamp, Sabih H. Gerez}
+\IEEEauthorblockA{%Computer Architecture for Embedded Systems (CAES)\\
+Department of EEMCS, University of Twente\\
P.O. Box 217, 7500 AE, Enschede, The Netherlands\\
c.p.r.baaij@@utwente.nl, matthijs@@stdin.nl, j.kuper@@utwente.nl}}
% \and
\begin{abstract}
%\boldmath
\CLaSH\ is a functional hardware description language that borrows both its
-syntax and semantics from the functional programming language Haskell. The use of polymorphism and higher-order functions allow a circuit designer to describe more abstract and general specifications than are possible in the traditional hardware description languages.
-
-Circuit descriptions can be translated to synthesizable VHDL using the prototype \CLaSH\ compiler. As the circuit descriptions are made in plain Haskell, simulations can also be compiled by any Haskell compiler.
+syntax and semantics from the functional programming language Haskell. Circuit
+descriptions can be translated to synthesizable VHDL using the prototype
+\CLaSH\ compiler. As the circuit descriptions are made in plain Haskell,
+simulations can also be compiled by a Haskell compiler.
+
+The use of polymorphism and higher-order functions allow a circuit designer to
+describe more abstract and general specifications than are possible in the
+traditional hardware description languages.
\end{abstract}
% IEEEtran.cls defaults to using nonbold math in the Abstract.
% This preserves the distinction between vectors and scalars. However,
\section{Introduction}
-Hardware description languages has allowed the productivity of hardware
+Hardware description languages have allowed the productivity of hardware
engineers to keep pace with the development of chip technology. Standard
Hardware description languages, like \VHDL~\cite{VHDL2008} and
Verilog~\cite{Verilog}, allowed an engineer to describe circuits using a
and types that together form the language primitives of the domain specific
language. As a result of how the signals are modeled and abstracted, the
functions used to describe a circuit also build a large domain-specific
-datatype (hidden from the designer) which can be further processed by an
+datatype (hidden from the designer) which can then be processed further by an
embedded compiler. This compiler actually runs in the same environment as the
description; as a result compile-time and run-time become hard to define, as
the embedded compiler is usually compiled by the same Haskell compiler as the
capture certain language constructs, such as Haskell's choice elements
(if-constructs, case-constructs, pattern matching, etc.), which are not
available in the functional hardware description languages that are embedded
-in Haskell as a domain specific languages. As far as the authors know, such
+in Haskell as a domain specific language. As far as the authors know, such
extensive support for choice-elements is new in the domain of functional
hardware description languages. As the hardware descriptions are plain Haskell
functions, these descriptions can be compiled for simulation using an
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, as such, only synchronous systems can be described. 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. 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.
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 called \CLaSH\
-(pronounced: clash), which 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.
+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.
+
+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
+shown to work for non-trivial descriptions. \CLaSH\ has been able to
+successfully translate the functional description of a streaming reduction
+circuit~\cite{reductioncircuit} for floating point numbers.
\section{Hardware description in Haskell}
\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
- function applications are assigned to a signal, which are then mapped to
+ 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
application itself.
\end{code}
\begin{figure}
- \centerline{\includegraphics{mac}}
+ \centerline{\includegraphics{mac.svg}}
\caption{Combinatorial Multiply-Accumulate}
\label{img:mac-comb}
\end{figure}
\end{code}
\begin{figure}
- \centerline{\includegraphics{mac-nocurry}}
+ \centerline{\includegraphics{mac-nocurry.svg}}
\caption{Combinatorial Multiply-Accumulate (complex input)}
\label{img:mac-comb-nocurry}
\end{figure}
% 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. 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}.
+ constructs, in the code below.
\begin{code}
sumif pred a b = case pred of
\end{code}
\begin{figure}
- \centerline{\includegraphics{choice-case}}
+ \centerline{\includegraphics{choice-case.svg}}
\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
matching. A function can be defined in multiple clauses, where each clause
(\Cref{img:choice}) as the earlier two versions of the example.
\begin{code}
- sumif Eq a b | a == b = a + b
- sumif Neq a b | a != b = a + b
- sumif _ _ _ = 0
+ sumif Eq a b | a == b = a + b
+ | otherwise = 0
+ sumif Neq a b | a != b = a + b
+ | otherwise = 0
\end{code}
% \begin{figure}
% value.
\item[\bf{Multiple constructors with fields}]
Algebraic datatypes with multiple constructors, where at least
- one of these constructors has one or more fields are not
- currently supported.
+ one of these constructors has one or more fields are currently not
+ supported.
\end{xlist}
\subsection{Polymorphism}
\end{code}
\begin{figure}
- \centerline{\includegraphics{mac-state}}
+ \centerline{\includegraphics{mac-state.svg}}
\caption{Stateful Multiply-Accumulate}
\label{img:mac-state}
\end{figure}
state, and what part of the output is part of the updated state. This
aspect will also reflected in the type signature of the function.
Abstracting the state of a circuit in this way makes it very explicit:
- which variables are part of the state is completely determined by the
+ which variables are part of the state is completely determined by the
type signature. This approach to state is well suited to be used in
combination with the existing code and language features, such as all the
choice constructs, as state values are just normal values. We can simulate
value in the input list corresponds to exactly one cycle of the (implicit)
clock. The result of the simulation is a list of outputs for every clock
cycle. As both the \hs{run} function and the hardware description are
- plain hardware, the complete simulation can be compiled by an optimizing
+ plain Haskell, the complete simulation can be compiled by an optimizing
Haskell compiler.
\section{\CLaSH\ prototype}
-foo\par bar
+The \CLaSH\ language as presented above can be translated to \VHDL\ using
+the prototype \CLaSH\ compiler. This compiler allows experimentation with
+the \CLaSH\ language and allows for running \CLaSH\ designs on actual FPGA
+hardware.
+
+\begin{figure}
+\centerline{\includegraphics{compilerpipeline.svg}}
+\caption{\CLaSH\ compiler pipeline}
+\label{img:compilerpipeline}
+\end{figure}
+
+The prototype heavily uses \GHC, the Glasgow Haskell Compiler.
+\Cref{img:compilerpipeline} shows the \CLaSH\ compiler pipeline. As you can
+see, the front-end is completely reused from \GHC, which allows the \CLaSH\
+prototype to support most of the Haskell Language. The \GHC\ front-end
+produces the program in the \emph{Core} format, which is a very small,
+functional, typed language which is relatively easy to process.
+
+The second step in the compilation process is \emph{normalization}. This
+step runs a number of \emph{meaning preserving} transformations on the
+Core program, to bring it into a \emph{normal form}. This normal form
+has a number of restrictions that make the program similar to hardware.
+In particular, a program in normal form no longer has any polymorphism
+or higher order functions.
+
+The final step is a simple translation to \VHDL.
\section{Use cases}
+\label{sec:usecases}
As an example of a common hardware design where the use of higher-order
functions leads to a very natural description is a FIR filter, which is
basically the dot-product of two vectors:
xs *+* ys = foldl1 (+) (zipWith (*) xs hs)
\end{code}
-The \hs{zipWith} function is very similar to the \hs{map} function: It
-takes a function, two vectors, and then applies the function to each of
-the elements in the two vectors pairwise (\emph{e.g.}, \hs{zipWith (*) [1,
-2] [3, 4]} becomes \hs{[1 * 3, 2 * 4]} $\equiv$ \hs{[3,8]}).
+The \hs{zipWith} function is very similar to the \hs{map} function seen
+earlier: It takes a function, two vectors, and then applies the function to
+each of the elements in the two vectors pairwise (\emph{e.g.}, \hs{zipWith (*)
+[1, 2] [3, 4]} becomes \hs{[1 * 3, 2 * 4]} $\equiv$ \hs{[3,8]}).
The \hs{foldl1} function takes a function, a single vector, and applies
the function to the first two elements of the vector. It then applies the
is depicted in \Cref{img:4tapfir}.
\begin{figure}
-\centerline{\includegraphics{4tapfir}}
+\centerline{\includegraphics{4tapfir.svg}}
\caption{4-taps FIR Filter}
\label{img:4tapfir}
\end{figure}
The ForSyDe~\cite{ForSyDe2} system uses Haskell to specify abstract system
models, which can (manually) be transformed into an implementation model using
-semantic preserving transformations. ForSyDe has several simulation and
-synthesis backends, though synthesis is restricted to the synchronous subset
-of the ForSyDe language.
+semantic preserving transformations. A designer can model systems using
+heterogeneous models of computation, which include continuous time,
+synchronous and untimed models of computation. Using so-called domain
+interfaces a designer can simulate electronic systems which have both analog
+as digital parts. ForSyDe has several backends including simulation and
+automated synthesis, though automated synthesis is restricted to the
+synchronous model of computation within ForSyDe. Unlike \CLaSH\ there is no
+support for the automated synthesis of descriptions that contain polymorphism
+or higher-order functions.
Lava~\cite{Lava} is a hardware description language that focuses on the
structural representation of hardware. Besides support for simulation and
generators when viewed from a synthesis viewpoint, in that the language
elements of Haskell, such as choice, can be used to guide the circuit
generation. If a developer wants to insert a choice element inside an actual
-circuit he will have to specify this explicitly as a component. In this
-respect \CLaSH\ differs from Lava, in that all the choice elements, such as
-case-statements and pattern matching, are synthesized to choice elements in the
-eventual circuit. As such, richer control structures can both be specified and
-synthesized in \CLaSH\ compared to any of the languages mentioned in this
-section.
+circuit he will have to explicitly instantiate a multiplexer-like component.
+
+In this respect \CLaSH\ differs from Lava, in that all the choice elements,
+such as case-statements and pattern matching, are synthesized to choice
+elements in the eventual circuit. As such, richer control structures can both
+be specified and synthesized in \CLaSH\ compared to any of the languages
+mentioned in this section.
The merits of polymorphic typing, combined with higher-order functions, are
now also recognized in the `main-stream' hardware description languages,
-exemplified by the new \VHDL-2008 standard~\cite{VHDL2008}. \VHDL-2008 has
-support to specify types as generics, thus allowing a developer to describe
+exemplified by the new \VHDL-2008 standard~\cite{VHDL2008}. \VHDL-2008 support for generics has been extended to types, allowing a developer to describe
polymorphic components. Note that those types still require an explicit
-generic map, whereas type-inference and type-specialization are implicit in
-\CLaSH.
+generic map, whereas types can be automatically inferred in \CLaSH.
% Wired~\cite{Wired},, T-Ruby~\cite{T-Ruby}, Hydra~\cite{Hydra}.
%
% http://www.michaelshell.org/tex/ieeetran/bibtex/
\bibliographystyle{IEEEtran}
% argument is your BibTeX string definitions and bibliography database(s)
-\bibliography{IEEEabrv,clash.bib}
+\bibliography{clash}
%
% <OR> manually copy in the resultant .bbl file
% set second argument of \begin to the number of references