\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 application. These have a single obvious \small{VHDL} translation: Each
function becomes a hardware component, where each argument is an input port
and the result value is the output port.
%% \stopcombination
%}
-The first step in the core to VHDL translation process, is normalization. We
+The first step in the core to \small{VHDL} translation process, is normalization. We
aim to bring the core description into a simpler form, which we can
-subsequently translate into VHDL easily. This normal form is needed because
-the full core language is more expressive than VHDL in some areas and because
+subsequently translate into \small{VHDL} easily. This normal form is needed because
+the full core language is more expressive than \small{VHDL} in some areas and because
core can describe expressions that do not have a direct hardware
interpretation.
-TODO: Describe core properties not supported in VHDL, and describe how the
-VHDL we want to generate should look like.
+TODO: Describe core properties not supported in \small{VHDL}, and describe how the
+\small{VHDL} we want to generate should look like.
\section{Normal form}
The transformations described here have a well-defined goal: To bring the
generate a hardware signal that contains a function, so all values,
arguments and returns values used must be first order.
- \item Any complex \emph{nested scopes} must be removed. In the VHDL
+ \item Any complex \emph{nested scopes} must be removed. In the \small{VHDL}
description, every signal is in a single scope. Also, full expressions are
not supported everywhere (in particular port maps can only map signal names,
- not expressions). To make the VHDL generation easy, all values must be bound
+ not expressions). To make the \small{VHDL} generation easy, all values must be bound
on the \quote{top level}.
\stopitemize
define a component instantiation, where the input and output ports are mapped
to local signals or arguments. Some of the others use a builtin
construction (\eg the \lam{case} statement) or call a builtin function
-(\eg \lam{add} or \lam{sub}). For these, a hardcoded VHDL translation is
+(\eg \lam{add} or \lam{sub}). For these, a hardcoded \small{VHDL} translation is
available.
\subsection{Definitions}
This transformation inlines simple let bindings (\eg a = b).
This transformation is not needed to get into normal form, but makes the
-resulting VHDL a lot shorter.
+resulting \small{VHDL} a lot shorter.
\starttrans
letnonrec
(since ununsed bindings are not forbidden by the normal form), but in practice
the desugarer or simplifier emits some unused bindings that cannot be
normalized (e.g., calls to a \type{PatError} (TODO: Check this name)). Also,
-this transformation makes the resulting VHDL a lot shorter.
+this transformation makes the resulting \small{VHDL} a lot shorter.
\starttrans
let a = E in M
These arguments cannot be preserved in the program, since we
cannot represent them as input or output ports in the resulting
- VHDL. To remove them, we create a specialized version of the
+ \small{VHDL}. To remove them, we create a specialized version of the
called function with these arguments filled in. This is done by
the argument propagation transform.
\subsubsection{Argument simplification}
This transform deals with arguments to functions that
are of a runtime representable type. It ensures that they will all become
-references to global variables, or local signals in the resulting VHDL.
+references to global variables, or local signals in the resulting \small{VHDL}.
TODO: It seems we can map an expression to a port, not only a signal.
Perhaps this makes this transformation not needed?
This transformation is useful when applying higher order builtin functions
like \hs{map} to a lambda abstraction, for example. In this case, the code
-that generates VHDL for \hs{map} only needs to handle top level functions and
+that generates \small{VHDL} for \hs{map} only needs to handle top level functions and
partial applications, not any other expression (such as lambda abstractions or
even more complicated expressions).
newEmptyBox.inp(0,0);
newBox.front(btex \small{GHC} frontend + desugarer etex);
newBox.norm(btex Normalization etex);
- newBox.vhdl(btex VHDL generation etex);
+ newBox.vhdl(btex \small{VHDL} generation etex);
newEmptyBox.out(0,0);
% Space the boxes evenly
ObjLabel.inp(btex Haskell source etex) "labpathname(haskell)", "labdir(rt)";
ObjLabel.front(btex Core etex) "labpathname(core)", "labdir(rt)";
ObjLabel.norm(btex Normalized core etex) "labpathname(normal)", "labdir(rt)";
- ObjLabel.vhdl(btex VHDL description etex) "labpathname(vhdl)", "labdir(rt)";
+ ObjLabel.vhdl(btex \small{VHDL} description etex) "labpathname(vhdl)", "labdir(rt)";
% Draw the objects (and deferred labels)
drawObj (inp, front, norm, vhdl, out);
order expressions, has a specific structure, etc.), but is also very
close to directly describing hardware.
\stopdesc
- \startdesc{VHDL generation}
+ \startdesc{\small{VHDL} generation}
The last step takes the normal formed core representation and generates
- VHDL for it. Since the normal form has a specific, hardware-like
+ \small{VHDL} for it. Since the normal form has a specific, hardware-like
structure, this final step is very straightforward.
\stopdesc
As noted above, any component of a function's state that is a substate,
\eg passed on as the state of another function, should have no influence
on the hardware generated for the calling function. Any state-specific
- VHDL for this component can be generated entirely within the called
+ \small{VHDL} for this component can be generated entirely within the called
function. So,we can completely leave out substates from any function.
From this observation, we might think to remove the substates from a
function's states alltogether, and leave only the state components which
are actual states of the current function. While doing this would not
- remove any information needed to generate VHDL from the function, it would
+ remove any information needed to generate \small{VHDL} from the function, it would
cause the function definition to become invalid (since we won't have any
substate to pass to the functions anymore). We could solve the syntactic
problems by passing \type{undefined} for state variables, but that would
longer be semantically equivalent to the original input).
To keep the function definition correct until the very end of the process,
- we will not deal with (sub)states until we get to the VHDL generation.
- Here, we are translating from Core to VHDL, and we can simply not generate
- VHDL for substates, effectively removing the substate components
+ we will not deal with (sub)states until we get to the \small{VHDL} generation.
+ Here, we are translating from Core to \small{VHDL}, and we can simply not generate
+ \small{VHDL} for substates, effectively removing the substate components
alltogether.
There are a few important points when ignore substates.
In the example above, this means we should remove \type{accums'} from
\type{s'}, but not throw away \type{s'} entirely. We should, however,
remove \type{s'} from the output port of the function, since the state
- will be handled by a VHDL procedure within the function.
+ will be handled by a \small{VHDL} procedure within the function.
When looking at substates, these can appear in two places: As part of an
argument and as part of a return value. As noted above, these substates
can only be used in very specific ways.
- \desc{State variables can appear as an argument.} When generating VHDL, we
+ \desc{State variables can appear as an argument.} When generating \small{VHDL}, we
completely ignore the argument and generate no input port for it.
\desc{State variables can be extracted from other state variables.} When
extracting a state variable from another state variable, this always means
we're extracting a substate, which we can ignore. So, we simply generate no
- VHDL for any extraction operation that has a state variable as a result.
+ \small{VHDL} for any extraction operation that has a state variable as a result.
\desc{State variables can be passed to functions.} When passing a
state variable to a function, this always means we're passing a substate
\stopdesc
\desc{State variables can appear as (part of) a function result.} When
- generating VHDL, we can completely ignore any part of a function result
+ generating \small{VHDL}, we can completely ignore any part of a function result
that has a state type. If the entire result is a state type, this will
mean the entity will not have an output port. Otherwise, the state
elements will be removed from the type of the output port.
look at the whole, we can conclude the following:
\startitemize
- \item A state unpack operation should not generate any VHDL. The binder
+ \item A state unpack operation should not generate any \small{VHDL}. The binder
to which the unpacked state is bound should still be declared, this signal
will become the register and will hold the current state.
- \item A state pack operation should not generate any VHDL. The binder th
+ \item A state pack operation should not generate any \small{VHDL}. The binder th
which the packed state is bound should not be declared. The binder that is
packed is the signal that will hold the new state.
- \item Any values of a State type should not be translated to VHDL. In
+ \item Any values of a State type should not be translated to \small{VHDL}. In
particular, State elements should be removed from tuples (and other
datatypes) and arguments with a state type should not generate ports.
- \item To make the state actually work, a simple VHDL proc should be
+ \item To make the state actually work, a simple \small{VHDL} proc should be
generated. This proc updates the state at every clockcycle, by assigning
the new state to the current state. This will be recognized by synthesis
tools as a register specification.
might think it as having a state type. Since the state type has a single
argument constructor \type{State}, some type that should be the resulting
state should always be explicitly packed with the State constructor,
- allowing us to remove the packed version, but still generate VHDL for the
+ allowing us to remove the packed version, but still generate \small{VHDL} for the
unpacked version (of course with any substates removed).
As you can see, the definition of \type{s'} is still present, since it