X-Git-Url: https://git.stderr.nl/gitweb?p=matthijs%2Fmaster-project%2Fdsd-paper.git;a=blobdiff_plain;f=c%CE%BBash.lhs;h=f0eae8433aaf7e23cde09fda7df2bd3826eaf172;hp=1b681c6430fe0114bf9d83b84c490741a559a3b5;hb=20bcf9d86e5e6c2b40cbb48e55274a8f60054dcd;hpb=d5514ab5ff0a8b65c145eb88accd868c222b5a2b diff --git "a/c\316\273ash.lhs" "b/c\316\273ash.lhs" index 1b681c6..f0eae84 100644 --- "a/c\316\273ash.lhs" +++ "b/c\316\273ash.lhs" @@ -360,7 +360,7 @@ \setlength{\leftmargin}{\labelwidth} \addtolength{\leftmargin}{\labelsep} \setlength{\rightmargin}{0pt} - \setlength{\parsep}{0.5ex plus 0.2ex minus 0.1ex} + \setlength{\listparindent}{\parindent} \setlength{\itemsep}{0 ex plus 0.2ex} \renewcommand{\makelabel}[1]{##1:\hfil} } @@ -368,6 +368,8 @@ {\end{list}} \usepackage{paralist} +\usepackage{xcolor} +\def\comment#1{{\color[rgb]{1.0,0.0,0.0}{#1}}} %include polycode.fmt %include clash.fmt @@ -463,50 +465,62 @@ The abstract goes here. \section{Introduction} Hardware description languages has allowed the productivity of hardware engineers to keep pace with the development of chip technology. Standard -Hardware description languages, like \VHDL\ and Verilog, allowed an engineer -to describe circuits using a programming language. These standard languages -are very good at describing detailed hardware properties such as timing -behavior, but are generally cumbersome in expressing higher-level -abstractions. These languages also tend to have a complex syntax and a lack of -formal semantics. To overcome these complexities, and raise the abstraction -level, a great number of approaches based on functional languages has been -proposed \cite{T-Ruby,Hydra,HML2,Hawk1,Lava,ForSyDe1,Wired,reFLect}. The idea -of using functional languages started in the early 1980s \cite{Cardelli1981, -muFP,DAISY,FHDL}, a time which also saw the birth of the currently popular -hardware description languages such as \VHDL. What gives functional languages -as hardware description languages their merits is the fact that basic -combinatorial circuits are equivalent to mathematical function, and that -functional languages lend themselves very well to describe and compose these -mathematical functions. +Hardware description languages, like \VHDL~\cite{VHDL2008} and +Verilog~\cite{Verilog}, allowed an engineer to describe circuits using a +programming language. These standard languages are very good at describing +detailed hardware properties such as timing behavior, but are generally +cumbersome in expressing higher-level abstractions. In an attempt to raise the +abstraction level of the descriptions, a great number of approaches based on +functional languages has been proposed \cite{T-Ruby,Hydra,HML2,Hawk1,Lava, +ForSyDe1,Wired,reFLect}. The idea of using functional languages for hardware +descriptions started in the early 1980s \cite{Cardelli1981, muFP,DAISY,FHDL}, +a time which also saw the birth of the currently popular hardware description +languages such as \VHDL. The merit of using a functional language to describe +hardware comes from the fact that basic combinatorial circuits are equivalent +to mathematical functions and that functional languages are very good at +describing and composing mathematical functions. In an attempt to decrease the amount of work involved with creating all the required tooling, such as parsers and type-checkers, many functional hardware description languages are embedded as a domain specific language inside the -functional language Haskell \cite{Hydra,Hawk1,Lava,ForSyDe1,Wired}. What this -means is that a developer is given a library of Haskell functions and types -that together form the language primitives of the domain specific language. -Using these functions, the designer does not only describes a circuit, but -actually builds a large domain-specific datatype which can be further -processed 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 circuit description itself. +functional language Haskell \cite{Hydra,Hawk1,Lava,ForSyDe1,Wired}. This +means that a developer is given a library of Haskell~\cite{Haskell} functions +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 +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 +circuit description itself. The approach taken in this research is not to make another domain specific -language embedded in Haskell, but to use (a subset) of the Haskell language -itself to be used as hardware description language. By taking this approach, -we can capture certain language constructs, such as Haskell's choice elements -(if-statement, case-statment, etc.), which are not available in the functional -hardware description languages that are embedded in Haskell. As far as the -authors know, such extensive support for choice-elements is new in the domain -of functional hardware description language. As the hardware descriptions are -plain Haskell functions, these descriptions can be compiled for simulation -using using the optimizing Haskell compiler \GHC. +language embedded in Haskell, but to use (a subset of) the Haskell language +itself for the purpose of describing hardware. By taking this approach, we can +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 +extensive support for choice-elements is new in the domain of functional +hardware description language. As the hardware descriptions are plain Haskell +functions, these descriptions can be compiled for simulation using using the +optimizing Haskell compiler \GHC. + +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. The functions describe the behavior of the hardware between +clock cycles, as such, only synchronous systems can be described. Many +functional hardware description models 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 languages must eventually be converted into a -netlist. This research also features an a prototype translater 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 optimizing \VHDL\ synthesis tools. +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 optimizing \VHDL\ synthesis tools. \section{Hardware description in Haskell} @@ -538,7 +552,7 @@ netlist. This research also features an a prototype translater called \CLaSH\ mac a b c = add (mul a b) c \end{code} - TODO: Pretty picture +\comment{TODO: Pretty picture} \subsection{Choices} Although describing components and connections allows describing a @@ -570,26 +584,26 @@ mac a b c = add (mul a b) c expression, one using only case expressions and one using pattern matching and guards. -\begin{code} -sumif pred a b = if pred == Eq && a == b || - pred == Neq && a != b - then a + b - else 0 - -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 - -sumif Eq a b | a == b = a + b -sumif Neq a b | a != b = a + b -sumif _ _ _ = 0 -\end{code} + \begin{code} + sumif pred a b = if pred == Eq && a == b || + pred == Neq && a != b + then a + b + else 0 + + 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 + + sumif Eq a b | a == b = a + b + sumif Neq a b | a != b = a + b + sumif _ _ _ = 0 + \end{code} - TODO: Pretty picture + \comment{TODO: Pretty picture} \subsection{Types} Translation of two most basic functional concepts has been @@ -603,7 +617,7 @@ sumif _ _ _ = 0 every \emph{type} used in a hardware description is needed. The following types are \emph{built-in}, meaning that their hardware - translation is fixed into the \CLaSH compiler. A designer can also + translation is fixed into the \CLaSH\ compiler. A designer can also define his own types, which will be translated into hardware types using translation rules that are discussed later on. @@ -627,61 +641,54 @@ sumif _ _ _ = 0 length type, so you can define an unsigned word of 32 bits wide as follows: -\begin{code} -type Word32 = SizedWord D32 -\end{code} + \begin{code} + type Word32 = SizedWord D32 + \end{code} 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 \VHDL\ \texttt{unsigned} and - \texttt{signed} respectively. + making the \hs{Word32} type a 32-bit unsigned word. These types are + translated to the \VHDL\ \texttt{unsigned} and \texttt{signed} + respectively. \item[\hs{Vector}] This is a vector type, that can contain elements of any other type and - has a fixed length. - - 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: + has a fixed length. 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: -\begin{code} -type RegisterState = Vector D8 Word32 -\end{code} + \begin{code} + type RegisterState = Vector D8 Word32 + \end{code} 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 \VHDL\ array type. + 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 \VHDL\ array type. \item[\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. - - The main purpose of the \hs{RangedWord} type is to be used as an - index to a \hs{Vector}. - - TODO: Perhaps remove this example? + implicitly zero. The main purpose of the \hs{RangedWord} type is to be + used as an index to a \hs{Vector}. - To define an index for the 8 element vector above, we would do: + \comment{TODO: Perhaps remove this example?} To define an index for + the 8 element vector above, we would do: -\begin{code} -type RegisterIndex = RangedWord D7 -\end{code} + \begin{code} + type RegisterIndex = RangedWord D7 + \end{code} 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 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 \texttt{unsigned} \VHDL type. + 8 element vector \hs{RegisterState} above. This type is translated to + the \texttt{unsigned} \VHDL type. \end{xlist} \subsection{User-defined types} @@ -708,9 +715,8 @@ type RegisterIndex = RangedWord D7 \item[\bf{Single constructor}] Algebraic datatypes with a single constructor with one or more fields, are essentially a way to pack a few values together in a - record-like structure. - - An example of such a type is the following pair of integers: + record-like structure. An example of such a type is the following pair + of integers: \begin{code} data IntPair = IntPair Int Int @@ -718,21 +724,16 @@ data IntPair = IntPair Int Int Haskell's builtin tuple types are also defined as single constructor algebraic types and are translated according to this - rule by the \CLaSH compiler. - - These types are translated to \VHDL\ record types, with one field for - every field in the constructor. + rule by the \CLaSH\ compiler. These types are translated to \VHDL\ + record types, with one field for every field in the constructor. \item[\bf{No fields}] Algebraic datatypes with multiple constructors, but without any fields are essentially a way to get an enumeration-like type - containing alternatives. - - Note that Haskell's \hs{Bool} type is also defined as an - enumeration type, but we have a fixed translation for that. - - These types are translated to \VHDL\ enumerations, with one value for - each constructor. This allows references to these constructors to be - translated to the corresponding enumeration value. + containing alternatives. Note that Haskell's \hs{Bool} type is also + defined as an enumeration type, but we have a fixed translation for + that. These types are translated to \VHDL\ enumerations, with one + value for each constructor. This allows references to these + constructors to be translated to the corresponding enumeration 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 @@ -822,7 +823,7 @@ 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 +exemplified by the new \VHDL-2008 standard~\cite{VHDL2008}. \VHDL-2008 has support to specify types as generics, thus 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