--- /dev/null
+\chapter{Hardware description}
+ This chapter will provide an overview of the hardware description language
+ that was created and the issues that have arisen in the process. It will
+ focus on the issues of the language, not the implementation.
+
+ When translating Haskell to hardware, we need to make choices in what kind
+ of hardware to generate for what Haskell constructs. When faced with
+ choices, we've tried to stick with the most obvious choice wherever
+ possible. In a lot of cases, when you look at a hardware description it is
+ comletely clear what hardware is described. We want our translator to
+ generate exactly that hardware whenever possible, to minimize the amount of
+ surprise for people working with it.
+
+ In this chapter we try to describe how we interpret a Haskell program from a
+ hardware perspective. We provide a description of each Haskell language
+ element that needs translation, to provide a clear picture of what is
+ supported and how.
+
+ \section{Function application}
+ The basic syntactic element of a functional program are functions and
+ function application. These have a single obvious VHDL translation: Each
+ function becomes a hardware component, where each argument is an input port
+ and the result value is the output port.
+
+ Each function application in turn becomes component instantiation. Here, the
+ result of each argument expression is assigned to a signal, which is mapped
+ to the corresponding input port. The output port of the function is also
+ mapped to a signal, which is used as the result of the application.
+
+ An example of a simple program using only function application would be:
+
+ \starthaskell
+ -- | A simple function that returns the and of three bits
+ and3 :: Bit -> Bit -> Bit -> Bit
+ and3 a b c = and (and a b) c
+ \stophaskell
+
+ This results in the following hardware:
+
+ TODO: Pretty picture
+
+ \subsection{Partial application}
+ It should be obvious that we cannot generate hardware signals for all
+ expressions we can express in Haskell. The most obvious criterium for this
+ is the type of an expression. We will see more of this below, but for now it
+ should be obvious that any expression of a function type cannot be
+ represented as a signal or i/o port to a component.
+
+ From this, we can see that the above translation rules do not apply to a
+ partial application. Let's look at an example:
+
+ \starthaskell
+ -- | Multiply the input word by four.
+ quadruple :: Word -> Word
+ quadruple n = mul (mul n)
+ where
+ mul = (*) 2
+ \stophaskell
+
+ It should be clear that the above code describes the following hardware:
+
+ TODO: Pretty picture
+
+ Here, the definition of mul is a partial function application: It applies
+ \hs{2 :: Word} to the function \hs{(*) :: Word -> Word -> Word} resulting in
+ the expression \hs{(*) 2 :: Word -> Word}. Since this resulting expression
+ is again a function, we can't generate hardware for it directly. This is
+ because the hardware to generate for \hs{mul} depends completely on where
+ and how it is used. In this example, it is even used twice!
+
+ However, it is clear that the above hardware description actually describes
+ valid hardware. In general, we can see that any partial applied function
+ must eventually become completely applied, at which point we can generate
+ hardware for it using the rules for function application above. It might
+ mean that a partial application is passed around quite a bit (even beyond
+ function boundaries), but eventually, the partial application will become
+ completely applied.
+
+ \section{Recursion}
+ An import concept in functional languages is recursion. In it's most basic
+ form, recursion is a function that is defined in terms of itself. This
+ usually requires multiple evaluations of this function, with changing
+ arguments, until eventually an evaluation of the function no longer requires
+ itself.
+
+ Recursion in a hardware description is a bit of a funny thing. Usually,
+ recursion is associated with a lot of nondeterminism, stack overflows, but
+ also flexibility and expressive power.
+
+ Given the notion that each function application will translate to a
+ component instantiation, we are presented with a problem. A recursive
+ function would translate to a component that contains itself. Or, more
+ precisely, that contains an instance of itself. This instance would again
+ contain an instance of itself, and again, into infinity. This is obviously a
+ problem for generating hardware.
+
+ This is expected for functions that describe infinite recursion. In that
+ case, we can't generate hardware that shows correct behaviour in a single
+ cycle (at best, we could generate hardware that needs an infinite number of
+ cycles to complete).
+
+ However, most recursive hardware descriptions will describe finite
+ recursion. This is because the recursive call is done conditionally. There
+ is usually a case statement where at least one alternative does not contain
+ the recursive call, which we call the "base case". If, for each call to the
+ recursive function, we would be able to detect which alternative applies,
+ we would be able to remove the case expression and leave only the base case
+ when it applies. This will ensure that expanding the recursive functions
+ will terminate after a bounded number of expansions.
+
+ This does imply the extra requirement that the base case is detectable at
+ compile time. In particular, this means that the decision between the base
+ case and the recursive case must not depend on runtime data.
+
+ \subsection{List recursion}
+ The most common deciding factor in recursion is the length of a list that is
+ passed in as an argument. Since we represent lists as vectors that encode
+ the length in the vector type, it seems easy to determine the base case. We
+ can simply look at the argument type for this. However, it turns out that
+ this is rather non-trivial to write down in Haskell in the first place. As
+ an example, we would like to write down something like this:
+
+ \starthaskell
+ sum :: Vector n Word -> Word
+ sum xs = case null xs of
+ True -> 0
+ False -> head xs + sum (tail xs)
+ \stophaskell
+
+ However, the typechecker will now use the following reasoning (element type
+ of the vector is left out):
+
+ \startitemize
+ \item tail has the type \hs{(n > 0) => Vector n -> Vector (n - 1)}
+ \item This means that xs must have the type \hs{(n > 0) => Vector n}
+ \item This means that sum must have the type \hs{(n > 0) => Vector n -> a}
+ \item sum is called with the result of tail as an argument, which has the
+ type \hs{Vector n} (since \hs{(n > 0) => n - 1 == m}).
+ \item This means that sum must have the type \hs{Vector n -> a}
+ \item This is a contradiction between the type deduced from the body of sum
+ (the input vector must be non-empty) and the use of sum (the input vector
+ could have any length).
+ \stopitemize
+
+ As you can see, using a simple case at value level causes the type checker
+ to always typecheck both alternatives, which can't be done! This is a
+ fundamental problem, that would seem perfectly suited for a type class.
+ Considering that we need to switch between to implementations of the sum
+ function, based on the type of the argument, this sounds like the perfect
+ problem to solve with a type class. However, this approach has its own
+ problems (not the least of them that you need to define a new typeclass for
+ every recursive function you want to define).
+
+ Another approach tried involved using GADTs to be able to do pattern
+ matching on empty / non empty lists. While this worked partially, it also
+ created problems with more complex expressions.
+
+ TODO: How much detail should there be here? I can probably refer to
+ Christiaan instead.
+
+ Evaluating all possible (and non-possible) ways to add recursion to our
+ descriptions, it seems better to leave out list recursion alltogether. This
+ allows us to focus on other interesting areas instead. By including
+ (builtin) support for a number of higher order functions like map and fold,
+ we can still express most of the things we would use list recursion for.
+
+ \subsection{General recursion}
+ Of course there are other forms of recursion, that do not depend on the
+ length (and thus type) of a list. For example, simple recursion using a
+ counter could be expressed, but only translated to hardware for a fixed
+ number of iterations. Also, this would require extensive support for compile
+ time simplification (constant propagation) and compile time evaluation
+ (evaluation constant comparisons), to ensure non-termination. Even then, it
+ is hard to really guarantee termination, since the user (or GHC desugarer)
+ might use some obscure notation that results in a corner case of the
+ simplifier that is not caught and thus non-termination.
+
+ Due to these complications, we leave other forms of recursion as
+ future work as well.