aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-06-23 23:46:18 -0700
committerazidar2015-06-23 23:46:18 -0700
commite56077d90071efe2e2c6c6e09dccaeae9b52cee7 (patch)
treeeb3f30f1e3bd616af39ca411fce54438375957ac
parent72e3136927c84b9e94ff544a1fa63c3633837f95 (diff)
More updates to spec
-rw-r--r--spec/spec.pdfbin238615 -> 239446 bytes
-rw-r--r--spec/spec.tex345
2 files changed, 188 insertions, 157 deletions
diff --git a/spec/spec.pdf b/spec/spec.pdf
index ba748fe2..eba33222 100644
--- a/spec/spec.pdf
+++ b/spec/spec.pdf
Binary files differ
diff --git a/spec/spec.tex b/spec/spec.tex
index c882e976..55a80721 100644
--- a/spec/spec.tex
+++ b/spec/spec.tex
@@ -28,7 +28,6 @@
\begin{document}
\maketitle
\tableofcontents
-\newpage
%Useful Macros
\newcommand{\id}{\text{id }}
@@ -46,13 +45,12 @@
\subsection{Background}
The ideas for FIRRTL originated from a different UC Berkeley project, Chisel, which embedded a hardware description language in Scala and was used to write highly-parameterized circuit designs.
+(TODO - explain how the concepts of Chisel are great)
-Paragraph explaining how the concepts of Chisel are great.
-
-\subsection{Motivation}
-Internally, Chisel successfully enabled our research in computer architecture by becoming the backbone of our research infrastructure.
-Externally, many projects outside of UC Berkeley used Chisel to design their hardware.
-However, Chisel's external rate of adoption slowed for the following reasons:
+At UC Berkeley, Chisel provided the infrastructure to support computer architecture research, including vector machines, out-of-order processors, silicon photonics and cache coherency.
+Many of these projects were successfully taped-out in actual silicon - our research productivity proved to us the validity of our design methodology.
+(TODO - Number of students and timeline)
+However, Chisel's external rate of adoption was slow for the following reasons:
\begin{enumerate}[topsep=3pt,itemsep=-0.5ex,partopsep=1ex,parsep=1ex]
\item Learning a functional language (Scala) was a large barrier to entry
\item Conceptually separating the Chisel HDL from the host language was difficult for new users
@@ -62,35 +60,27 @@ However, Chisel's external rate of adoption slowed for the following reasons:
\item Chisel IR semantics were ill-defined and thus impossible to target from other languages
\end{enumerate}
-For these reasons, we felt Chisel needed to be redesigned from its ground up to formalize its IR and semantics, modularize its compilation process for robustness, and cleanly separate its frontend (Chisel + Scala), internal representation (FIRRTL), and backends.
+As a consequence, we felt Chisel needed to be redesigned from its ground up to standardize its IR and semantics, modularize its compilation process for robustness, and cleanly separate its frontend (Chisel + Scala), internal representation (FIRRTL), and backends.
-\subsection{Design Philosophy and Justification}
+\subsection{Design Philosophy}
FIRRTL represents the formalized elaborated graph that the Chisel DSL produces, prior to any simplification.
-By including complicated constructs like vector types, bundle types, and when statements in FIRRTL, the Chisel/Scala frontend can be as light-weight as possible.
-
-Low FIRRTL represents a simplified FIRRTL circuit that lacks any complex features and has additional structural invariants to make it a netlist of a circuit.
-This form is straightforward to transform into another language (e.g. Verilog) by a light-weight backend.
-
-By containing low FIRRTL within
+By including complicated constructs like vector types, bundle types, and when statements in FIRRTL, the Chisel/Scala frontend can be very light-weight.
+In addition, other front-ends written in languages other than Scala could be simple to write and increase external adoption.
+Lowered FIRRTL represents a simplified FIRRTL circuit with structural invariants, making it essentially a netlist.
+This form enables straightforward translation into another language (e.g. Verilog) by a light-weight backend.
-\begin{enumerate}[topsep=3pt,itemsep=-0.5ex,partopsep=1ex,parsep=1ex]
-\item Easy to make light-weight backends
-\item Easy to make light-weight front-ends
-\item Enables more complicated, but potentially more performant, backends that operate on high firrtl
-\item Lowering allows transforms to operate on a limited scope (low firrtl), but produce high firrtl, then lower again if needed.
-\item Specification allows additional people to contribute front-ends, back-ends, and custom transforms.
-\end{enumerate}
+By defining low FIRRTL as a structured subset of FIRRTL, an external user can write a transformational pass whose input is restricted, but whose output is full-featured.
+After a custom pass, the resulting circuit should undergo lowering prior to passing it to a backend or another custom pass.
\section{Acknowledgements - IN PROGRESS}
-
-The FIRRTL language could not have been developed without the help of many of the faculty and students in the ASPIRE lab, including but not limited to Andrew Waterman, Stephen Twigg, Palmer Dabbelt, Eric Love, Scott Beamer, Chris Celio, Krste Asanovic, and many many others.
+The FIRRTL language could not have been developed without the help of many of the faculty and students in the ASPIRE lab, including but not limited to XXXX.
We'd also like to thank our sponsors XXXX, and the UC Berkeley University.
\section{FIRRTL Language Definition}
\subsection{Abstract Syntax Tree}
-{\footnotesize
+{\small
\[
\begin{array}{rrll}
\pd{circuit} &= &\kw{circuit} \id \kw{:} (\pd{module*}) &\text{Circuit}\\
@@ -104,8 +94,7 @@ We'd also like to thank our sponsors XXXX, and the UC Berkeley University.
&\vert &\pds{type}[\ints] &\text{Vector}\\
\pd{field} &= &\pd{orientation} \id \kw{:} \pd{type} &\text{Bundle Field}\\
\pd{orientation}&= &\kws{default} \vert \kws{reverse} &\text{Orientation}\\
-\pd{width} &= &\ints &\text{Known Integer Width}\\
- &\vert &\kw{?} &\text{Unknown Width}\\
+\pd{width} &= &\ints \vert \kw{?} &\text{Known/Unknown Integer Width}\\
\pd{stmt} &= &\info \kw{wire} \id \kw{:} \pd{type} &\text{Wire Declaration}\\
&\vert &\info \kw{reg} \id \kw{:} \pds{type} , \ids , \pds{exp} &\text{Register Declaration}\\
&\vert &\info \kw{smem} \id \kw{:} \pds{type} , \ids &\text{Sequential Memory Declaration}\\
@@ -116,8 +105,8 @@ We'd also like to thank our sponsors XXXX, and the UC Berkeley University.
&\vert &\info \pd{exp} \kw{:=} \pd{exp} &\text{Connect}\\
&\vert &\info \kw{onreset} \pd{exp} \kw{:=} \pd{exp} &\text{On-Reset Connect}\\
&\vert &\info \pd{exp} \kw{$<>$} \pd{exp} &\text{Bulk Connect}\\
+ &\vert &\info \pds{exp}[\intsp \kw{through} \ints] \ \kw{:=} \pds{exp} &\text{Sub-Word Connect}\\
&\vert &\info \kw{when} \pd{exp} \kw{:} \pd{stmt} \kw{else :} \pd{stmt} &\text{Conditional}\\
- &\vert &\info \pds{exp}[\intsp \kw{through} \ints] \ \kw{:=} \pds{exp} &\text{Sub-Word Assignment}\\
&\vert &\info \kw{assert} \pd{exp} &\text{Assert Statement}\\
&\vert &\info \kw{skip} &\text{Empty Statement}\\
&\vert &\info (\pd{stmt*}) &\text{Statement Group}\\
@@ -133,46 +122,44 @@ We'd also like to thank our sponsors XXXX, and the UC Berkeley University.
\end{array}
\]
}
-
\[
-{\footnotesize
-\begin{array}{rll}
-\pd{primop} &= \\
- &\kws{add} &\text{Unsigned/Signed Add}\\
-\vert &\kws{sub} &\text{Unsigned/Signed Subtract}\\
-\vert &\kws{addw} &\text{Unsigned/Signed Add Wrap}\\
-\vert &\kws{subw} &\text{Unsigned/Signed Subtract Wrap}\\
-\vert &\kws{mul} &\text{Unsigned/Signed Multiply}\\
-\vert &\kws{div} &\text{Unsigned/Signed Divide}\\
-\vert &\kws{rem} &\text{Unsigned/Signed Remainder}\\
-\vert &\kws{quo} &\text{Unsigned/Signed Quotient}\\
-\vert &\kws{mod} &\text{Unsigned/Signed Modulo}\\
-\vert &\kws{lt} &\text{Unsigned/Signed Less Than}\\
-\vert &\kws{leq} &\text{Unsigned/Signed Less or Equal}\\
-\vert &\kws{gt} &\text{Unsigned/Signed Greater Than}\\
-\vert &\kws{geq} &\text{Unsigned/Signed Greater or Equal}\\
-\vert &\kws{eq} &\text{Unsigned/Signed Equal}\\
-\vert &\kws{neq} &\text{Unsigned/Signed Not-Equal}\\
-\vert &\kws{mux} &\text{Unsigned/Signed Multiplex}\\
-\vert &\kws{pad} &\text{Unsigned/Signed Pad to Length}\\
-\vert &\kws{asUInt} &\text{Unsigned/Signed Reinterpret Bits as UInt}\\
-\vert &\kws{asSInt} &\text{Unsigned/Signed Reinterpret Bits as SInt}\\
-\vert &\kws{shl} &\text{Unsigned/Signed Shift Left}\\
-\vert &\kws{shr} &\text{Unsigned/Signed Shift Right}\\
-\vert &\kws{dshl} &\text{Unsigned/Signed Dynamic Shift Left}\\
-\vert &\kws{dshr} &\text{Unsigned/Signed Dynamic Shift Right}\\
-\vert &\kws{cvt} &\text{Unsigned/Signed to Signed Logical Conversion}\\
-\vert &\kws{neg} &\text{Unsigned/Signed Negate}\\
-\vert &\kws{not} &\text{Unsigned Not}\\
-\vert &\kws{and} &\text{Unsigned And}\\
-\vert &\kws{or} &\text{Unsigned Or}\\
-\vert &\kws{xor} &\text{Unsigned Xor}\\
-\vert &\kws{andr} &\text{Unsigned And Reduce}\\
-\vert &\kws{orr} &\text{Unsigned Or Reduce}\\
-\vert &\kws{xorr} &\text{Unsigned Xor Reduce}\\
-\vert &\kws{cat} &\text{Unsigned Concatenation}\\
-\vert &\kws{bit} &\text{Single Bit Extraction}\\
-\vert &\kws{bits} &\text{Multiple Bit Extraction}\\
+{\small
+\begin{array}{rrll}
+\pd{primop} &= &\kws{add} &\text{Unsigned/Signed Add}\\
+ &\vert &\kws{sub} &\text{Unsigned/Signed Subtract}\\
+ &\vert &\kws{addw} &\text{Unsigned/Signed Add Wrap}\\
+ &\vert &\kws{subw} &\text{Unsigned/Signed Subtract Wrap}\\
+ &\vert &\kws{mul} &\text{Unsigned/Signed Multiply}\\
+ &\vert &\kws{div} &\text{Unsigned/Signed Divide}\\
+ &\vert &\kws{mod} &\text{Unsigned/Signed Modulo}\\
+ &\vert &\kws{quo} &\text{Unsigned/Signed Quotient}\\
+ &\vert &\kws{rem} &\text{Unsigned/Signed Remainder}\\
+ &\vert &\kws{lt} &\text{Unsigned/Signed Less Than}\\
+ &\vert &\kws{leq} &\text{Unsigned/Signed Less or Equal}\\
+ &\vert &\kws{gt} &\text{Unsigned/Signed Greater Than}\\
+ &\vert &\kws{geq} &\text{Unsigned/Signed Greater or Equal}\\
+ &\vert &\kws{eq} &\text{Unsigned/Signed Equal}\\
+ &\vert &\kws{neq} &\text{Unsigned/Signed Not-Equal}\\
+ &\vert &\kws{mux} &\text{Unsigned/Signed Multiplex}\\
+ &\vert &\kws{pad} &\text{Unsigned/Signed Pad to Length}\\
+ &\vert &\kws{asUInt} &\text{Unsigned/Signed Reinterpret Bits as UInt}\\
+ &\vert &\kws{asSInt} &\text{Unsigned/Signed Reinterpret Bits as SInt}\\
+ &\vert &\kws{shl} &\text{Unsigned/Signed Shift Left}\\
+ &\vert &\kws{shr} &\text{Unsigned/Signed Shift Right}\\
+ &\vert &\kws{dshl} &\text{Unsigned/Signed Dynamic Shift Left}\\
+ &\vert &\kws{dshr} &\text{Unsigned/Signed Dynamic Shift Right}\\
+ &\vert &\kws{cvt} &\text{Unsigned/Signed to Signed Logical Conversion}\\
+ &\vert &\kws{neg} &\text{Unsigned/Signed Negate}\\
+ &\vert &\kws{not} &\text{Unsigned Not}\\
+ &\vert &\kws{and} &\text{Unsigned And}\\
+ &\vert &\kws{or} &\text{Unsigned Or}\\
+ &\vert &\kws{xor} &\text{Unsigned Xor}\\
+ &\vert &\kws{andr} &\text{Unsigned And Reduce}\\
+ &\vert &\kws{orr} &\text{Unsigned Or Reduce}\\
+ &\vert &\kws{xorr} &\text{Unsigned Xor Reduce}\\
+ &\vert &\kws{cat} &\text{Unsigned Concatenation}\\
+ &\vert &\kws{bit} &\text{Single Bit Extraction}\\
+ &\vert &\kws{bits} &\text{Multiple Bit Extraction}\\
\end{array}
}
\]
@@ -194,8 +181,8 @@ Readers and writers are provided for converting a FIRRTL datastructure into a pu
\pd{circuit} &= &\kw{circuit} \text{toplevel-module } \kw{:} (\text{modules*}) \\
\pd{module} &= &\kw{module} \text{name } \kw{:} (\text{ports* } \text{body}) \\
&\vert &\kw{exmodule} \text{name } \kw{:} (\text{ports* }) \\
-\pd{port} &= &\pd{dir} \id \kw{:} \pd{type} \\
-\pd{dir} &= &\kws{input} \vert \kws{output} \vert \kws{clock} \\
+\pd{port} &= &\pd{kind} \id \kw{:} \pd{type} \\
+\pd{kind} &= &\kws{input} \vert \kws{output} \vert \kws{clock} \\
\end{array}
\]
@@ -204,11 +191,11 @@ Each module has a given name, a list of ports, and a statement representing the
Externally defined modules consist of a given name, and a list of ports, whose types must match the types defined in the associated Verilog.
Module names exist in their own namespace, and all modules must have a unique name. The name of the top-level module must be specified for a circuit.
-A module port is specified by a direction, which may be input or output or clock, a name, and the data type for the port.
+A module port is specified by its kind, which may be input or output or clock, a name, and the data type for the port.
The port names exist in the identifier namespace for the module, and must be unique.
In addition, all references within a module must be unique.
-The clock port direction is special in that it cannot be used to connect to any element in the circuit.
+The clock port kind is special in that it cannot be used to connect to any element in the circuit.
However, a clock port can be referenced in the \kws{reg}, \kws{cmem}, \kws{smem}, and \kws{inst} declarations, as explained in Section \ref{statements}.
The following example shows how a module can span two clock domains:
@@ -218,6 +205,7 @@ The following example shows how a module can span two clock domains:
&\quad \kw{clock} clk1 \\
&\quad \kw{clock} clk2 \\
&\quad \kw{input} ... \\
+&\quad ... \\
\end{aligned}
\]
@@ -265,14 +253,18 @@ The type $\kws{UInt}\kws{$<$} 16 \kws{$>$}[10][5]$ indicates a five element vect
\]
Bundle types in FIRRTL are composite types formed from an ordered sequence of named, nested types.
-All fields in a bundle must have a given direction, name, and type.
+All fields in a bundle must have a given orientation, name, and type.
+
The following is an example of a possible type for representing a complex number.
\[
\bundleT{\kw{default} \text{real } \kw{:} \kws{SInt}\kws{$<$} 10 \kws{$>$},
\kw{default} \text{imag } \kw{:} \kws{SInt}\kws{$<$} 10 \kws{$>$}}
\]
It has two fields, real, and imag, both 10-bit signed integers.
-Here is an example of a possible type for a decoupled port.
+By convention, we specify the directions within a bundle type with their relative orientation.
+For this reason, the real and imag fields for the complex number bundle type are both specified to be {\em default}.
+
+The following bundle type has a data field that is specified to be a 10-bit unsigned integer type, a valid signal that must be a 1-bit unsigned integer type, and a reversed ready signal that must be a 1-bit unsigned integer type.
\[
\begin{aligned}
\{ \kw{default} &\text{data } \kw{:} \kws{UInt}\kws{$<$} 10 \kws{$>$}, \\
@@ -280,11 +272,7 @@ Here is an example of a possible type for a decoupled port.
\kw{reverse} &\text{ready } \kw{:} \kws{UInt}\kws{$<$} 1 \kws{$>$}\} \\
\end{aligned}
\]
-It has a data field that is specified to be a 10-bit unsigned integer, a valid signal that must be a 1-bit unsigned integer, and a reversed ready signal that must be a 1-bit unsigned integer.
-
-By convention, we specify the directions within a bundle type with their relative orientation.
-For this reason, the real and imag fields for the complex number bundle type are both specified to be {\em default}.
-Similarly, if a module were to output a value using a decoupled protocol, we would declare the module to have an output port, data, which would contain the value itself, a default field, valid, which would indicate when the value is valid, and accept an {\em reverse} field, ready, from the receiving component, which would indicate when the component is ready to receive the value.
+If an output port had this bundle type, the {\em ready} field would be an input to the module.
Note that all field names within a bundle type must be unique.
@@ -313,7 +301,7 @@ A register with a given name, type, clock port name, and reset reference, can be
Like wires, registers are also {\em bidirectional}, which means that they can be used as both an input (by being on the left-hand side of a connect statement), or as an output (by being on the right-hand side of a connect statement).
-The statement {\em onreset} is used to specify the initialization value for a register, which is assigned to the register when the declared \pds{reset} signal is asserted.
+The on reset statement is used to specify the initialization value for a register, which is assigned to the register when the declared \pds{reset} signal is asserted.
\subsection{Memories}
A memory is a stateful circuit element containing multiple elements.
@@ -352,13 +340,13 @@ Consequentially, their expression cannot be a bundle type with any reversed fiel
\subsection{Accessors}
Accessors are used for either connecting to or from a vector-typed expression, from some {\em variable} index.
-An accessor can be instantiated with the following statement.
\[
\begin{aligned}
&\pd{dir} \kw{accessor} \text{name} = \pds{exp}[\text{index}] \\
+\pd{dir} &= \kws{infer} \vert \kws{read} \vert \kws{write} \vert \kw{rdwr} \\
\end{aligned}
\]
-Given a direction, a name, an expression to access, and the index at which to access, the above statement creates an accessor that may be used for connecting to or from the expression.
+Given an accessor direction, a name, an expression to access, and the index at which to access, the above statement creates an accessor that may be used for connecting to or from the expression.
The expression must have a vector type, and the index must be an variable of UInt type.
A read, write, and inferred accessor is conceptually one-way; it must be consistently used to connect to, or to connect from, but not both.
@@ -387,7 +375,7 @@ They can be used to access {\em any} vector-valued type.
\subsection{Instances}
An instance refers to a particular instantiation of a FIRRTL module.
-An instance with some given name, of a given module, with a list of clock ports can be created using the following statement.
+An instance is constructed with a given name, a given module name, and a list of clock ports.
\[
\begin{aligned}
\kw{inst} \text{name } \kw{:} \text{module}, \text{clk*}
@@ -463,21 +451,15 @@ The following statement is used to connect the output of some component, to the
\]
For a connection to be legal, the types of the two expressions must match exactly, including all field orientations if the elements contain bundle types.
-The component on the right-hand side must be able to be used as an output, and the component on the left-hand side must be able to be used as an input.
-\subsection{The Bulk Connect Statement}
-The bulk connect statement is a connect statement that does not require both expressions to be the same type.
-During the lowering pass, the bulk connect will expand to some number of connect statements, possibly zero statements.
-The following statement is used to connect the output of some component, to the input of another component.
-\[
-\text{input } \kw{$<>$} \text{output}
-\]
+However, the widths of the types do not need to be equivalent.
+If the {\em output} expression has a smaller width than the {\em input} expression, the {\em output} is padded according to its type.
+If the {\em output} expression has a larger width than the {\em input} expression, the lower bits of the {\em output} are extracted and assigned to the {\em input}.
-For a bulk connect between two components of a bundle-type, fields that are of the same type, orientation, and name will be connected.
-Fields that do not match will not be connected.
-For a bulk connect between two components of a vector-type, the number of connected elements will be equal to the length of the shorter vector.
-A bulk connect between two components of the same ground type is equivalent to a normal connect statement.
-All other combinations of types will not error, but will not generate any connect statements.
+If the {\em input} width is unknown, it is inferred to be the width of the largest {\em output} that it is connected to.
+If the {\em output} width is unknown, it cannot inferred from this connection.
+
+The component on the right-hand side must be able to be used as an output, and the component on the left-hand side must be able to be used as an input.
\subsection{The On-Reset Connect Statement}
The on reset connect statement is used to specify the default value for a \kws{reg} element.
@@ -487,6 +469,7 @@ The on reset connect statement is used to specify the default value for a \kws{r
For a connection to be legal, the types of the two expressions must match exactly, including all field orientations if the elements contain bundle types.
The component on the right-hand side must be able to be used as an output, and the component on the left-hand side must be a \kws{reg} element.
+The widths of the types may mismatch, and the semantics are the same as the connect statements.
Memories cannot be initialized with this construct.
By default, a \kws{reg} will not have a initialization value and will maintain its current value under the reset signal specified in their declaration.
@@ -499,10 +482,24 @@ The following example demonstrates declaring a \kws{reg}, and changing its initi
\end{aligned}
\]
+\subsection{The Bulk Connect Statement}
+The bulk connect statement is a connect statement that does not require both expressions to be the same type.
+During the lowering pass, the bulk connect will expand to some number of connect statements, possibly zero statements.
+The following statement is used to connect the output of some component, to the input of another component.
+\[
+\text{input } \kw{$<>$} \text{output}
+\]
+
+For a bulk connect between two components of a bundle-type, fields that are of the same type, orientation, and name will be connected.
+Fields that do not match will not be connected.
+For a bulk connect between two components of a vector-type, the number of connected elements will be equal to the length of the shorter vector.
+A bulk connect between two components of the same ground type is equivalent to a normal connect statement.
+All other combinations of types will not error, but will not generate any connect statements.
+
\subsection{The Sub-Word Connect Statement}
The subword connect statement is used to assigned to a range of bits within a ground-typed element. It is specified by two integers that indicate the high and low bounds of the range, inclusively.
\[
-\text{exp}[\text{hi} \kw{through} \text{lo}] \ \kw{:=} \text{output}
+\text{exp}[\text{hi } \kw{through} \text{lo}] \ \kw{:=} \text{output}
\]
The subword is always UInt type, so for a connection to be legal, the expression on the right must also be of UInt type.
@@ -523,7 +520,7 @@ Notationally, for convenience, we omit the \kws{else} branch if it is an empty s
\subsubsection{Initialization Coverage}
Because of the conditional statement, it is possible for wires to be only partially connected to an expression.
-In the following example, the wire w is connected to 42 when enable is asserted high, but it is not specified what w is connected to when enable is low.
+In the following example, the wire {\em w} is connected to 42 when enable is asserted high, but it is not specified what {\em w} is connected to when enable is low.
This is an illegal FIRRTL circuit, and will throw a \kws{wire not initialized} error during compilation.
\[
\begin{aligned}
@@ -542,6 +539,8 @@ Thus, there cannot be two components with identical names in the same module, {\
This is to facilitate writing transformational passes, by ensuring that the component name and module name is sufficient to uniquely identify a component.
\subsubsection{Connect Semantics - IN PROGRESS}
+A when creates a mux between the stuff outside and the stuff inside - acts as a "conditional barrier".
+If you draw a line between being connected to, and being declared, those connections are conditional on the whens on the line
\subsection{Statement Groups}
Several statements can be grouped into one using the following construct.
@@ -629,7 +628,7 @@ A reference may refer to a port, a node, a wire, a register, an instance, a memo
\[
\pds{exp}.\text{name}
\]
-The subfield expression may be used for one of three purposes:
+The subfield expression may be used for one of two purposes:
\begin{enumerate}
\item To refer to a specific port of an instance, using instance-name.port-name.
\item To refer to a specific field within a bundle-typed expression.
@@ -657,9 +656,6 @@ All primitive operations expression operands must be ground types.
In addition, some allow all permutations of operand ground types, while others on allow subsets.
When well defined, input arguments are allowed to be differing widths.
-FAQ: Why have generic operations instead of explicit types (e.g. add-uu, where the two inputs are unsigned)
-FAQ: Why allow operations to allow inputs of differing widths?
-
\subsection{Add Operation}
\[
\begin{array}{rll}
@@ -670,7 +666,6 @@ FAQ: Why allow operations to allow inputs of differing widths?
\kws{add}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) + 1 \\
\end{array}
\]
-
The resultant's value is 1-bit larger than the wider of the two operands and has a signed type if either operand is signed (otherwise is unsigned).
\subsection{Subtract Operation}
@@ -685,6 +680,32 @@ The resultant's value is 1-bit larger than the wider of the two operands and has
\]
The subtraction operation works similarly to the add operation, but always returns a signed integer with a width that is 1-bit wider than the max of the widths of the two operands.
+\subsection{Add Wrap Operation}
+\[
+\begin{array}{rll}
+\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
+\kws{addw}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
+\kws{addw}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
+\kws{addw}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
+\kws{addw}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
+\end{array}
+\]
+The add wrap operation works identically to the normal add operation except that the resultant width is the maximum of the width of the two operands, instead of 1 bit greater than the maximum.
+In the case of overflow, the result silently rolls over.
+
+\subsection{Subtract Wrap Operation}
+\[
+\begin{array}{rll}
+\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
+\kws{subw}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
+\kws{subw}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
+\kws{subw}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
+\kws{subw}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
+\end{array}
+\]
+Similarly to the add wrap operation, the subtract wrap operation works identically to the normal subtract operation except that the resultant width is the maximum of the width of the two operands.
+In the case of overflow, the result silently rolls over.
+
\subsection{Multiply Operation}
\[
\begin{array}{rll}
@@ -756,33 +777,6 @@ The first argument is the dividend, the second argument is the divisor.
The resultant width of a modulus operation is equal to the width of the divisor, except when the divisor is positive and the result can be negative.
The resultant value follows the following formula : quo(a,b) = floor(a/b) + rem(a,b)
-
-\subsection{Add Wrap Operation}
-\[
-\begin{array}{rll}
-\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
-\kws{add-wrap}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
-\kws{add-wrap}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
-\kws{add-wrap}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
-\kws{add-wrap}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
-\end{array}
-\]
-The add wrap operation works identically to the normal add operation except that the resultant width is the maximum of the width of the two operands, instead of 1 bit greater than the maximum.
-In the case of overflow, the result silently rolls over.
-
-\subsection{Subtract Wrap Operation}
-\[
-\begin{array}{rll}
-\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
-\kws{sub-wrap}(\pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
-\kws{sub-wrap}(\pds{op1}:UInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
-\kws{sub-wrap}(\pds{op1}:SInt, \pds{op2}:UInt) & SInt & max(width(op1),width(op2)) \\
-\kws{sub-wrap}(\pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
-\end{array}
-\]
-Similarly to the add wrap operation, the subtract wrap operation works identically to the normal subtract operation except that the resultant width is the maximum of the width of the two operands.
-In the case of overflow, the result silently rolls over.
-
\subsection{Comparison Operations}
\[
\begin{array}{rll}
@@ -805,7 +799,7 @@ In the case of overflow, the result silently rolls over.
\kws{geq} (\pds{op1}:SInt, \pds{op2}:SInt) & UInt & 1 \\
\end{array}
\]
-Each operation accept any combination of SInt or UInt input arguements, and always returns a single-bit unsigned integer.
+Each operation accept any combination of SInt or UInt input arguments, and always returns a single-bit unsigned integer.
\subsection{Equality Comparison}
\[
@@ -837,8 +831,8 @@ If an arithmetic not-equals between a signed and unsigned integer is desired, on
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
-\kws{mux} (\pds{condition}, \pds{op1}, \pds{op2}) & UInt & width(op1) \\
-\kws{mux} (\pds{condition}, \pds{op1}, \pds{op2}) & SInt & width(op1) \\
+\kws{mux} (\pds{condition}:UInt, \pds{op1}:UInt, \pds{op2}:UInt) & UInt & max(width(op1),width(op2)) \\
+\kws{mux} (\pds{condition}:UInt, \pds{op1}:SInt, \pds{op2}:SInt) & SInt & max(width(op1),width(op2)) \\
\end{array}
\]
The multiplex operation accepts three signals, a 1-bit unsigned integer for the condition expression, followed by either two unsigned integers, or two signed integers.
@@ -856,7 +850,7 @@ The output is of the same width as the max width of the inputs.
\end{array}
\]
A pad operation is provided which either zero-extends or sign-extends an expression to a specified width.
-The given width must be equal to or greater than the existing width of the expression.
+The given width, num, must be equal to or greater than the existing width of the expression.
\subsection{Reinterpret Bits as UInt}
\[
@@ -930,12 +924,12 @@ The shift amount must be less than or equal to the width of the operand.
The output of a shift right operation is equal to the original signal with the least significant $n$ bits truncated, where $n$ is the dynamic shift amount.
The output width of a dynamic shift right operation is the width of the original signal.
-\subsection{Convert to Signed}
+\subsection{Logical Convert to Signed}
\[
\begin{array}{rll}
\kws{primop} & \kws{Resultant Type} & \kws{Resultant Width} \\
-\kws{convert}(\pds{op}:UInt) & SInt & width(op) + 1 \\
-\kws{convert}(\pds{op}:SInt) & SInt & width(op) \\
+\kws{cvt}(\pds{op}:UInt) & SInt & width(op) + 1 \\
+\kws{cvt}(\pds{op}:SInt) & SInt & width(op) \\
\end{array}
\]
The convert operation accepts either an unsigned or a signed integer.
@@ -1011,19 +1005,20 @@ An index of zero indicates the least significant bit in the operand, and an inde
\end{array}
\]
The bit range extraction operation accepts either an unsigned or a signed integer, plus two integer literals that specify the high (inclusive) and low (inclusive) index of the bit range to extract.
+The index must be non-negative and less than the width of the operand.
Regardless of the type of the operand, the resultant value is a $n$-bit unsigned integer, where $n = \text{high} - \text{low} + 1$.
\section{FIRRTL Forms}
-To simplify the writing of transformation passes, FIRRTL provides a {\em resolving} pass, which resolves all types, widths, and checks the legality of the circuit, and a {\em lowering} pass, which rewrites any FIRRTL circuit into an equivalent {\em lowered form}.
+To simplify the writing of transformation passes, any FIRRTL implementation will provide a {\em resolving} pass, which resolves all types, widths, and checks the legality of the circuit, and a {\em lowering} pass, which rewrites any FIRRTL circuit into an equivalent {\em lowered form}.
-\subsection{Resolved Circuit}
+\subsection{Resolved Form}
-The resolved form is guaranteed to be well-formed, meaning all restrictions to a FIRRTL circuit have been checked. In addition, all unknown widths have been resolved.
+The resolved form is guaranteed to be well-formed, meaning all restrictions to a FIRRTL circuit have been checked. In addition, all unknown widths and inferred accessor directions have been resolved.
-\subsection{Lowered Circuit}
+\subsection{Lowered Form}
-The lowered form has the advantage of not having high-level constructs or composite types, and hence is a minimal representation that is convenient for low-level transforms.
+The lowered form is a structured subset of FIRRTL, making it a minimal representation that is convenient for low-level transforms.
The body of a lowered module consists of a list of declarations, connect statements, and {\em predicated single connect statements}.
A predicated single connect statement is a conditional statement containing a single connect statement and no else branch.
@@ -1037,31 +1032,29 @@ The following circuit is lowered:
&\quad \kw{input} \text{inc : UInt$<$1$>$} \\
&\quad \kw{output} \text{out : UInt$<$3$>$} \\
&\quad \kw{reg} \text{counter : UInt$<$3$>$, clk, reset} \\
-&\quad \kw{when} \text{inc : counter := addw(counter, UInt(1))} \\
+&\quad \kw{when} \text{inc : counter := addw(counter, UInt$<$1$>$(1))} \\
&\quad \text{out := counter} \\
\end{aligned}
\]
The following restrictions also hold for modules in lowered form.
-\subsubsection{No Nested Expressions}
+\begin{itemize}
+\item \kws{No Nested Expressions} :
In the declaration of the structural elements, the only nested expressions allowed are references, and unsigned and signed literals.
All other nested expressions must be lifted to a named node, and referred to through a reference.
-
-\subsubsection{No Composite Types}
+\item \kws{No Composite Types} :
No module port or wire may be declared with a bundle or vector type.
The lowering pass will recursively expand ports into its constituent elements until all ports are declared with ground types.
-
-\subsubsection{Single Connect}
+\item \kws{Single Connect} :
Every declared component can only be connected to once within a module.
This connect could be a predicated single connect.
-
-\subsubsection{No Nested Whens}
+\item \kws{No Nested Whens} :
Other than predicated single connect statements, no other conditional statements are allowed.
-
-\subsection{Inlined Lowering Form}
+\item \kws{Inlined Lowered Form} :
A further (and optional) pass provided by FIRRTL is the inlining pass, which recursively inlines all instances in the top-level module until the top-level module is the only remaining module in the circuit.
Inlined lowered form is essentially a flat netlist which specifies every component used in a circuit and their input connections.
+\end{itemize}
\section{Annotations - IN PROGRESS}
\begin{enumerate}[topsep=3pt,itemsep=-0.5ex,partopsep=1ex,parsep=1ex]
@@ -1087,10 +1080,10 @@ Identifiers cannot begin with a digit.
Comments begin with a semicolon and extend until the end of the line.
Commas are treated as whitespace, and may be used by the user for clarity if desired.
-Statements are grouped into statement groups using parenthesis, however a colon at the end of a line will automatically surround the next indented region with parenthesis.
+Statements are grouped into statement groups using parenthesis, however a colon at the end of a line will automatically assume the next indented region is a statement group.
This mechanism is used for indicating block structuring.
-The following circuit, module, port and statement examples all exclude the info token \verb|@[filename:line.col]|, which can be optionally included at the end of the first line of each elements' concrete syntax.
+The following circuit, module, port and statement examples all exclude the info token \verb|@[filename:line.col]|, which can be optionally included at the beginning of the first line of each elements' concrete syntax.
\subsection*{Circuits and Modules}
A circuit is specified the following way.
@@ -1135,7 +1128,7 @@ UInt<?>
SInt<?>
\end{verbatim}
-The bundle type consists of a number of fields surrounded with parenthesis.
+The bundle type consists of a number of fields surrounded with braces.
The following shows an example of a decoupled bundle type.
Note that the commas are for clarity only and are not necessary.
\begin{verbatim}
@@ -1151,7 +1144,7 @@ UInt<16>[10]
\end{verbatim}
\subsection*{Statements}
-The following examples demonstrate declaring wires, registers, memories, nodes, instances, accessors and bi-accessors.
+The following examples demonstrate declaring wires, registers, memories, nodes, instances, and accessors.
\begin{verbatim}
wire mywire : UInt<10>
reg myreg : UInt<10>, clk, reset
@@ -1247,8 +1240,9 @@ add(x, add(x, y))
shl(x, 42)
\end{verbatim}
-\section{Future FIRRTL Specification Plans - IN PROGRESS}
-Some choices were made during the design of this specification which were intentionally conservative, so that future versions could lift the restrictions if suitable semantics and implementations are determined. By restricting this version and potentially lifting them in future versions, all existing FIRRTL circuits will remain valid.
+\section{Future Plans - IN PROGRESS}
+Some choices were made during the design of this specification which were intentionally conservative, so that future versions could lift the restrictions if suitable semantics and implementations are determined.
+By restricting this version and potentially lifting these restrictions in future versions, all existing FIRRTL circuits will remain valid.
The follow design decisions could potentially be changed in future spec revisions:
\begin{enumerate}[topsep=3pt,itemsep=-0.5ex,partopsep=1ex,parsep=1ex]
@@ -1261,5 +1255,42 @@ The follow design decisions could potentially be changed in future spec revision
\item Not requiring that all names are unique
\end{enumerate}
+\section{FAQ - IN PROGRESS}
+\begin{enumerate}[topsep=3pt,itemsep=-0.5ex,partopsep=1ex,parsep=1ex]
+\item Why allow operations to allow inputs of differing widths?
+We tried restricting widths, but it actually complicated width inference and made supporting frontends with more lax width restrictions very difficult.
+Because there is perfectly well defined semantics, we opted to allow differing widths.
+In line with the Linux "funnel" philosophy of being accepting with your inputs and restrictive with your outputs.
+
+\item Why require all names unique?
+Passes usually need unique names, so there needs to be a renaming pass somewhere.
+Standardizing how names gets mangled requires a lot of thought, and we didn't feel comfortable putting this into the spec at the moment and potentially regretting it later.
+For now, names have to be unique, and it is the frontend's responsibility to do this.
+
+\item Why allow declaring components in when statements?
+We want the important property that a module is just a box of components inside - for any jumble of components, you can always lace them in the box, and it will preserve the semantics.
+You need to declare wires inside whens - because generators could run within a when in a frontend.
+You should always be able to pull them into a module if we want.
+Now its inconsistent if you can't declare registers in the scope.
+
+\item Why not just have low firrtl?
+Low firrtl leaves out general when usage, vector and bundle types, and requires a single connect.
+For performance backends, we will need to emit arrays and structs.
+If there is only a lowered circuit, we lose that ability.
+We cannot simply add vector/bundle types to low firrtl as frontends cannot easily remove whens without removing the complex types as well.
+Instead, one will need the expressiveness in firrtl to write a performant backend which does not need to operate on low firrtl.
+
+\item Why have asserts?
+Up for debate.
+
+\item Why disallow zero-width wires?
+Very tricky to get the semantics correct.
+On the todo list.
+
+\item Why not require default value for wires? Isn't this a SAT problem?
+We do the same thing that is done in Java, and is standard programming language practice.
+
+\end{enumerate}
+
\end{document}