+ Since every top level function generates its own component, the
+ hierarchy of of function calls is reflected in the final \VHDL\ output
+ as well, creating a hierarchical \VHDL\ description of the hardware.
+ This separation in different components makes the resulting \VHDL\
+ output easier to read and debug.
+
+ \in{Example}[ex:And3] shows a simple program using only function
+ application and the corresponding architecture.
+
+\startbuffer[And3]
+-- A simple function that returns
+-- conjunction of three bits
+and3 :: Bit -> Bit -> Bit -> Bit
+and3 a b c = and (and a b) c
+\stopbuffer
+
+ \startuseMPgraphic{And3}
+ save a, b, c, anda, andb, out;
+
+ % I/O ports
+ newCircle.a(btex $a$ etex) "framed(false)";
+ newCircle.b(btex $b$ etex) "framed(false)";
+ newCircle.c(btex $c$ etex) "framed(false)";
+ newCircle.out(btex $out$ etex) "framed(false)";
+
+ % Components
+ newCircle.anda(btex $and$ etex);
+ newCircle.andb(btex $and$ etex);
+
+ a.c = origin;
+ b.c = a.c + (0cm, 1cm);
+ c.c = b.c + (0cm, 1cm);
+ anda.c = midpoint(a.c, b.c) + (2cm, 0cm);
+ andb.c = midpoint(b.c, c.c) + (4cm, 0cm);
+
+ out.c = andb.c + (2cm, 0cm);
+
+ % Draw objects and lines
+ drawObj(a, b, c, anda, andb, out);
+
+ ncarc(a)(anda) "arcangle(-10)";
+ ncarc(b)(anda);
+ ncarc(anda)(andb);
+ ncarc(c)(andb);
+ ncline(andb)(out);
+ \stopuseMPgraphic
+
+ \startbuffer[And3VHDL]
+ entity and3Component_0 is
+ port (\azMyG2\ : in std_logic;
+ \bzMyI2\ : in std_logic;
+ \czMyK2\ : in std_logic;
+ \foozMySzMyS2\ : out std_logic;
+ clock : in std_logic;
+ resetn : in std_logic);
+ end entity and3Component_0;
+
+
+ architecture structural of and3Component_0 is
+ signal \argzMyMzMyM2\ : std_logic;
+ begin
+ \argzMyMzMyM2\ <= \azMyG2\ and \bzMyI2\;
+
+ \foozMySzMyS2\ <= \argzMyMzMyM2\ and \czMyK2\;
+ end architecture structural;
+ \stopbuffer
+
+ \placeexample[][ex:And3]{Simple three input and gate.}
+ \startcombination[2*1]
+ {\typebufferhs{And3}}{Haskell description using function applications.}
+ {\boxedgraphic{And3}}{The architecture described by the Haskell description.}
+ \stopcombination
+
+ \placeexample[][ex:And3VHDL]{\VHDL\ generated for \hs{and3} from \in{example}[ex:And3]}
+ {\typebuffervhdl{And3VHDL}}
+
+ \placeintermezzo{}{
+ \defref{top level binding}
+ \defref{top level binder}
+ \defref{top level function}
+ \startframedtext[width=8cm,background=box,frame=no]
+ \startalignment[center]
+ {\tfa Top level binders and functions}
+ \stopalignment
+ \blank[medium]
+ A \emph{top level binder} is any binder (variable) that is
+ declared in the \quote{global} scope of a Haskell program (as
+ opposed to a binder that is bound inside a function. The binder
+ together with its body is referred to as a \emph{top level
+ binding}.
+
+ In Haskell, there is no sharp distinction between a variable and a
+ function: a function is just a variable (binder) with a function
+ type. This means that a \emph{top level function} is just any top
+ level binder with a function type. This also means that sometimes
+ top level function will be used when top level binder is really
+ meant.
+
+ As an example, consider the following Haskell snippet:
+
+ \starthaskell
+ foo :: Int -> Int
+ foo x = inc x
+ where
+ inc = \y -> y + 1
+ \stophaskell
+
+ Here, \hs{foo} is a top level binder, whereas \hs{inc} is a
+ function (since it is bound to a lambda extraction, indicated by
+ the backslash) but is not a top level binder or function. Since
+ the type of \hs{foo} is a function type, namely \hs{Int -> Int},
+ it is also a top level function.
+ \stopframedtext
+ }
+ \section{Choice}
+ Although describing components and connections allows us to describe a lot of
+ hardware designs already, there is an obvious thing missing: choice. We
+ need some way to be able to choose between values based on another value.
+ In Haskell, choice is achieved by \hs{case} expressions, \hs{if}
+ expressions, pattern matching and guards.
+
+ An obvious way to add choice to our language without having to recognize
+ any of Haskell's syntax, would be to add a primitive \quote{\hs{if}}
+ function. This function would take three arguments: the condition, the
+ value to return when the condition is true and the value to return when
+ the condition is false.
+
+ This \hs{if} function would then essentially describe a multiplexer and
+ allows us to describe any architecture that uses multiplexers.
+
+ However, to be able to describe our hardware in a more convenient way, we
+ also want to translate Haskell's choice mechanisms. The easiest of these
+ are of course case expressions (and \hs{if} expressions, which can be very
+ directly translated to \hs{case} expressions). A \hs{case} expression can in turn
+ simply be translated to a conditional assignment, where the conditions use
+ equality comparisons against the constructors in the \hs{case} expressions.
+
+ In \in{example}[ex:Inv] two versions of an inverter are shown. The first
+ uses a simple \hs{case} expression, scrutinizing a Boolean value. The
+ corresponding architecture has a comparator to determine which of the
+ constructors is on the \hs{in} input. There is a multiplexer to select the
+ output signal (which is just a conditional assignment in the generated
+ \VHDL). The two options for the output signals are just constants,
+ but these could have been more complex expressions (in which case also
+ both of them would be working in parallel, regardless of which output
+ would be chosen eventually). The \VHDL\ generated for (both versions of)
+ this inverter is shown in \in{example}[ex:InvVHDL].
+
+ If we would translate a Boolean to a bit value, we could of course remove
+ the comparator and directly feed 'in' into the multiplexer (or even use an
+ inverter instead of a multiplexer). However, we will try to make a
+ general translation, which works for all possible \hs{case} expressions.
+ Optimizations such as these are left for the \VHDL\ synthesizer, which
+ handles them very well.
+
+ \placeintermezzo{}{
+ \startframedtext[width=8cm,background=box,frame=no]
+ \startalignment[center]
+ {\tfa Arguments / results vs. inputs / outputs}
+ \stopalignment
+ \blank[medium]
+ Due to the translation chosen for function application, there is a
+ very strong relation between arguments, results, inputs and outputs.
+ For clarity, the former two will always refer to the arguments and
+ results in the functional description (either Haskell or Core). The
+ latter two will refer to input and output ports in the generated
+ \VHDL.
+
+ Even though these concepts seem to be nearly identical, when stateful
+ functions are introduces we will see arguments and results that will
+ not get translated into input and output ports, making this
+ distinction more important.
+ \stopframedtext
+ }
+
+ A slightly more complex (but 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
+ corresponding clause will be used.
+
+ \in{Example}[ex:Inv] also shows an inverter that uses pattern matching.
+ The architecture it describes is of course the
+ same one as the description with a case expression. The general interpretation
+ of pattern matching is also similar to that of \hs{case} expressions: generate
+ hardware for each of the clauses (like each of the clauses of a \hs{case}
+ expression) and connect them to the function output through (a number of
+ nested) multiplexers. These multiplexers are driven by comparators and
+ other logic, that check each pattern in turn.
+
+ In these examples we have seen only binary case expressions and pattern
+ matches (\ie, with two alternatives). In practice, case expressions can
+ choose between more than two values, resulting in a number of nested
+ multiplexers.
+
+ \startbuffer[CaseInv]
+ inv :: Bool -> Bool
+ inv x = case x of
+ True -> False
+ False -> True
+ \stopbuffer
+
+ \startbuffer[PatternInv]
+ inv :: Bool -> Bool
+ inv True = False
+ inv False = True
+ \stopbuffer
+
+ \startuseMPgraphic{Inv}
+ save in, truecmp, falseout, trueout, out, cmp, mux;
+
+ % I/O ports
+ newCircle.in(btex $in$ etex) "framed(false)";
+ newCircle.out(btex $out$ etex) "framed(false)";
+ % Constants
+ newBox.truecmp(btex $True$ etex) "framed(false)";
+ newBox.trueout(btex $True$ etex) "framed(false)";
+ newBox.falseout(btex $False$ etex) "framed(false)";
+
+ % Components
+ newCircle.cmp(btex $==$ etex);
+ newMux.mux;
+
+ in.c = origin;
+ cmp.c = in.c + (3cm, 0cm);
+ truecmp.c = cmp.c + (-1cm, 1cm);
+ mux.sel = cmp.e + (1cm, -1cm);
+ falseout.c = mux.inpa - (2cm, 0cm);
+ trueout.c = mux.inpb - (2cm, 0cm);
+ out.c = mux.out + (2cm, 0cm);
+
+ % Draw objects and lines
+ drawObj(in, out, truecmp, trueout, falseout, cmp, mux);
+
+ ncline(in)(cmp);
+ ncarc(truecmp)(cmp);
+ nccurve(cmp.e)(mux.sel) "angleA(0)", "angleB(-90)";
+ ncline(falseout)(mux) "posB(inpa)";
+ ncline(trueout)(mux) "posB(inpb)";
+ ncline(mux)(out) "posA(out)";
+ \stopuseMPgraphic
+
+ \startbuffer[InvVHDL]
+ entity invComponent_0 is
+ port (\xzAMo2\ : in boolean;
+ \reszAMuzAMu2\ : out boolean;
+ clock : in std_logic;
+ resetn : in std_logic);
+ end entity invComponent_0;
+
+
+ architecture structural of invComponent_0 is
+ begin
+ \reszAMuzAMu2\ <= false when \xzAMo2\ = true else
+ true;
+ end architecture structural;
+ \stopbuffer
+
+ \placeexample[][ex:Inv]{Simple inverter.}{
+ % Use placesidebyside, since nesting combinations doesn't seem to work
+ % here. This does break centering, but well...
+ \placesidebyside
+ % Use 2*2 instead of 1*2 to insert some extra space (\placesidebyside
+ % places stuff very close together)
+ {\startcombination[2*2]
+ {\typebufferhs{CaseInv}}{Haskell description using a Case expression.}
+ {}{}
+ {\typebufferhs{PatternInv}}{Haskell description using Pattern matching expression.}
+ {}{}
+ \stopcombination}
+ % Use a 1*1 combination to add a caption
+ {\startcombination[1*1]
+ {\boxedgraphic{Inv}}{The architecture described by the Haskell descriptions.}
+ \stopcombination}
+ }
+
+% \placeexample[][ex:Inv]{Simple inverter.}{
+% \startcombination[2*2]
+% {\typebufferhs{CaseInv}}{Haskell description using a Case expression.}
+% {}{}
+% {\typebufferhs{PatternInv}}{Haskell description using Pattern matching expression.}
+% {\boxedgraphic{Inv}}{The architecture described by the Haskell description.}
+% \stopcombination
+% }
+ \placeexample[][ex:InvVHDL]{\VHDL\ generated for (both versions of) \hs{inv} from \in{example}[ex:Inv]}
+ {\typebuffervhdl{InvVHDL}}
+
+ \section{Types}
+ Translation of two most basic functional concepts has been
+ discussed: function application and choice. Before looking further
+ into less obvious concepts like higher-order expressions and
+ polymorphism, the possible types that can be used in hardware
+ descriptions will be discussed.
+
+ Some way is needed to translate every values used to its hardware
+ equivalents. In particular, this means a hardware equivalent for
+ every \emph{type} used in a hardware description is needed
+
+ Since most functional languages have a lot of standard types that
+ are hard to translate (integers without a fixed size, lists without
+ a static length, etc.), a number of \quote{built-in} types will be
+ defined first. These types are built-in in the sense that our
+ compiler will have a fixed VHDL type for these. User defined types,
+ on the other hand, will have their hardware type derived directly
+ from their Haskell declaration automatically, according to the rules
+ sketched here.
+
+ \todo{Introduce Haskell type syntax (type constructors, type application,
+ :: operator?)}
+
+ \subsection{Built-in types}
+ The language currently supports the following built-in types. Of these,
+ only the \hs{Bool} type is supported by Haskell out of the box (the
+ others are defined by the Cλash package, so they are user-defined types
+ from Haskell's point of view).
+
+ \startdesc{\hs{Bit}}
+ This is the most basic type available. It is mapped directly onto
+ the \type{std_logic} \small{VHDL} type. Mapping this to the
+ \type{bit} type might make more sense (since the Haskell version
+ only has two values), but using \type{std_logic} is more standard
+ (and allowed for some experimentation with don't care values)
+
+ \todo{Sidenote bit vs stdlogic}
+ \stopdesc
+ \startdesc{\hs{Bool}}
+ This is the only built-in Haskell type supported and is translated
+ exactly like the Bit type (where a value of \hs{True} corresponds to a
+ value of \hs{High}). Supporting the Bool type is particularly
+ useful to support \hs{if ... then ... else ...} expressions, which
+ always have a \hs{Bool} value for the condition.
+
+ A \hs{Bool} is translated to a \type{std_logic}, just like \hs{Bit}.
+ \stopdesc
+ \startdesc{\hs{SizedWord}, \hs{SizedInt}}
+ These are types to represent integers. A \hs{SizedWord} is unsigned,
+ while a \hs{SizedInt} is signed. These types are parametrized by a
+ length type, so you can define an unsigned word of 32 bits wide as
+ follows:
+
+ \starthaskell
+ type Word32 = SizedWord D32
+ \stophaskell
+
+ Here, a type synonym \hs{Word32} is defined that is equal to the
+ \hs{SizedWord} type constructor applied to the type \hs{D32}. \hs{D32}
+ is the \emph{type level representation} of the decimal number 32,
+ making the \hs{Word32} type a 32-bit unsigned word.
+
+ These types are translated to the \small{VHDL} \type{unsigned} and
+ \type{signed} respectively.
+ \todo{Sidenote on dependent typing?}
+ \stopdesc
+ \startdesc{\hs{Vector}}
+ This is a vector type, that can contain elements of any other type and
+ has a fixed length. It has two type parameters: its
+ length and the type of the elements contained in it. By putting the
+ length parameter in the type, the length of a vector can be determined
+ at compile time, instead of only at run-time for conventional lists.
+
+ The \hs{Vector} type constructor takes two type arguments: the length
+ of the vector and the type of the elements contained in it. The state
+ type of an 8 element register bank would then for example be:
+
+ \starthaskell
+ type RegisterState = Vector D8 Word32
+ \stophaskell
+
+ Here, a type synonym \hs{RegisterState} is defined that is equal to
+ the \hs{Vector} type constructor applied to the types \hs{D8} (The type
+ level representation of the decimal number 8) and \hs{Word32} (The 32
+ bit word type as defined above). In other words, the
+ \hs{RegisterState} type is a vector of 8 32-bit words.
+
+ A fixed size vector is translated to a \small{VHDL} array type.
+ \stopdesc
+ \startdesc{\hs{RangedWord}}
+ This is another type to describe integers, but unlike the previous
+ two it has no specific bit-width, but an upper bound. This means that
+ its range is not limited to powers of two, but can be any number.
+ A \hs{RangedWord} only has an upper bound, its lower bound is
+ implicitly zero. There is a lot of added implementation complexity
+ when adding a lower bound and having just an upper bound was enough
+ for the primary purpose of this type: type-safely indexing vectors.
+
+ To define an index for the 8 element vector above, we would do:
+
+ \starthaskell
+ type RegisterIndex = RangedWord D7
+ \stophaskell
+
+ Here, a type synonym \hs{RegisterIndex} is defined that is equal to
+ the \hs{RangedWord} type constructor applied to the type \hs{D7}. In
+ other words, this defines an unsigned word with values from
+ {\definedfont[Serif*normalnum]0 to 7} (inclusive). This word can be be used to index the
+ 8 element vector \hs{RegisterState} above.
+
+ This type is translated to the \type{unsigned} \small{VHDL} type.
+ \stopdesc