aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/spec.pdfbin270198 -> 274502 bytes
-rw-r--r--spec/spec.tex50
-rw-r--r--src/main/scala/firrtl/Compiler.scala2
-rw-r--r--src/main/scala/firrtl/annotations/JsonProtocol.scala2
-rw-r--r--src/main/scala/firrtl/options/DependencyManager.scala8
-rw-r--r--src/main/scala/firrtl/stage/package.scala2
-rw-r--r--src/test/scala/firrtlTests/CustomTransformSpec.scala27
7 files changed, 81 insertions, 10 deletions
diff --git a/spec/spec.pdf b/spec/spec.pdf
index a5e99700..833fb8cf 100644
--- a/spec/spec.pdf
+++ b/spec/spec.pdf
Binary files differ
diff --git a/spec/spec.tex b/spec/spec.tex
index a335709d..6bbd798f 100644
--- a/spec/spec.tex
+++ b/spec/spec.tex
@@ -162,7 +162,7 @@ Types are used to specify the structure of the data held by each circuit compone
\subsection{Ground Types}
-There are three ground types in FIRRTL: an unsigned integer type, a signed integer type, and a clock type.
+There are four ground types in FIRRTL: an unsigned integer type, a signed integer type, a clock type, and an analog type.
\subsubsection{Integer Types}
@@ -189,6 +189,34 @@ The clock type is specified as follows:
Clock
\end{lstlisting}
+\subsubsection{Analog Type}
+
+The analog type specifies that a wire or port can be attached to multiple drivers. \verb|Analog|
+cannot be used as the type of a node or register, nor can it be used as the datatype of a memory. In
+this respect, it is similar to how \verb|inout| ports are used in Verilog, and FIRRTL analog signals
+are often used to interface with external Verilog or VHDL IP.
+
+In contrast with all other ground types, analog signals cannot appear on either side of a connection
+statement. Instead, analog signals are attached to each other with the commutative \verb|attach|
+statement. An analog signal may appear in any number of attach statements, and a legal circuit may
+also contain analog signals that are never attached. The only primitive operations that may be
+applied to analog signals are casts to other signal types.
+
+When an analog signal appears as a field of an aggregate type, the aggregate cannot appear in a
+standard connection statement; however, the partial connection statement will \verb|attach|
+corresponding analog fields of its operands according to the partial connection algorithm described
+in Section \ref{partial_connection_algorithm}.
+
+As with integer types, an analog type can represent a multi-bit signal. When analog signals are not
+given a concrete width, their widths are inferred according to a highly restrictive width inference
+rule, which requires that the widths of all arguments to a given attach operation be identical.
+
+\begin{lstlisting}
+Analog<1> ; 1-bit analog type
+Analog<32> ; 32-bit analog type
+Analog ; analog type with inferred width
+\end{lstlisting}
+
\subsection{Vector Types}
A vector type is used to express an ordered sequence of elements of a given type. The length of the sequence must be non-negative and known.
@@ -356,7 +384,7 @@ For details on the syntax and semantics of the subfield expression, subindex exp
\subsubsection{The Partial Connection Algorithm} \label{partial_connection_algorithm}
-A partial connect statement between two ground type components connects the right-hand side expression to the left-hand side expression. Conversely, a {\em reverse} partial connect statement between two ground type components connects the left-hand side expression to the right-hand side expression.
+A partial connect statement between two non-analog ground type components connects the right-hand side expression to the left-hand side expression. Conversely, a {\em reverse} partial connect statement between two non-analog ground type components connects the left-hand side expression to the right-hand side expression. A partial connect statement between two analog-typed components performs an attach between the two signals.
A partial (or reverse partial) connect statement between two vector typed components applies a partial (or reverse partial) connect from the first n subelements in the right-hand side expression to the first n corresponding subelements in the left-hand side expression, where n is the length of the shorter vector.
@@ -513,6 +541,24 @@ Invalidating a component with a vector type recursively invalidates each subelem
Invalidating a component with a bundle type recursively invalidates each subelement in the bundle.
+\subsection{Attaches}
+
+The \verb|attach| statement is used to attach two or more analog signals, defining that their
+values be the same in a commutative fashion that lacks the directionality of a regular connection.
+It can only be applied to signals with analog type, and each analog signal may be attached zero or
+more times.
+
+\begin{lstlisting}
+wire x: Analog<2>
+wire y: Analog<2>
+wire z: Analog<2>
+attach(x, y) ; binary attach
+attach(z, y, x) ; attach all three signals
+\end{lstlisting}
+
+When signals of aggregate types that contain analog-typed fields are used as operators of a partial
+connection, corresponding fields of analog type are attached, rather than connected.
+
\subsection{Nodes}
A node is simply a named intermediate value in a circuit. The node must be initialized to a value with a passive type and cannot be connected to. Nodes are often used to split a complicated compound expression into named subexpressions.
diff --git a/src/main/scala/firrtl/Compiler.scala b/src/main/scala/firrtl/Compiler.scala
index 600b991e..9014d213 100644
--- a/src/main/scala/firrtl/Compiler.scala
+++ b/src/main/scala/firrtl/Compiler.scala
@@ -171,7 +171,7 @@ final case object UnknownForm extends CircuitForm(-1) {
/** The basic unit of operating on a Firrtl AST */
abstract class Transform extends TransformLike[CircuitState] {
/** A convenience function useful for debugging and error messages */
- def name: String = this.getClass.getSimpleName
+ def name: String = this.getClass.getName
/** The [[firrtl.CircuitForm]] that this transform requires to operate on */
def inputForm: CircuitForm
/** The [[firrtl.CircuitForm]] that this transform outputs */
diff --git a/src/main/scala/firrtl/annotations/JsonProtocol.scala b/src/main/scala/firrtl/annotations/JsonProtocol.scala
index c3853650..9992400a 100644
--- a/src/main/scala/firrtl/annotations/JsonProtocol.scala
+++ b/src/main/scala/firrtl/annotations/JsonProtocol.scala
@@ -109,7 +109,7 @@ object JsonProtocol {
val annos = parsed match {
case JArray(objs) => objs
case x => throw new InvalidAnnotationJSONException(
- s"Annotations must be serialized as a JArray, got ${x.getClass.getSimpleName} instead!")
+ s"Annotations must be serialized as a JArray, got ${x.getClass.getName} instead!")
}
// Recursively gather typeHints by pulling the "class" field from JObjects
// Json4s should emit this as the first field in all serialized classes
diff --git a/src/main/scala/firrtl/options/DependencyManager.scala b/src/main/scala/firrtl/options/DependencyManager.scala
index 1de8095b..604a1b10 100644
--- a/src/main/scala/firrtl/options/DependencyManager.scala
+++ b/src/main/scala/firrtl/options/DependencyManager.scala
@@ -291,7 +291,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
val nodes =
(prerequisiteGraph + dependentsGraph + invalidateGraph + otherDependents)
.getVertices
- .map(v => s"""${transformName(v)} [label="${v.getClass.getSimpleName}"]""")
+ .map(v => s"""${transformName(v)} [label="${v.getClass.getName}"]""")
s"""|digraph DependencyManager {
| graph [rankdir=BT]
@@ -315,8 +315,8 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
def rec(pm: DependencyManager[A, B], cm: Seq[String], tab: String = "", id: Int = 0): (String, Int) = {
var offset = id
- val targets = pm._targets.toSeq.map(_.getSimpleName).mkString(", ")
- val state = pm._currentState.toSeq.map(_.getSimpleName).mkString(", ")
+ val targets = pm._targets.toSeq.map(_.getName).mkString(", ")
+ val state = pm._currentState.toSeq.map(_.getName).mkString(", ")
val header = s"""|${tab}subgraph cluster_$id {
|$tab label="targets: $targets\\nstate: $state"
@@ -331,7 +331,7 @@ trait DependencyManager[A, B <: TransformLike[A] with DependencyAPI[B]] extends
case a =>
val name = s"""${transformName(a, "_" + id)}"""
sorted += name
- s"""$tab $name [label="${a.getClass.getSimpleName}"]"""
+ s"""$tab $name [label="${a.getClass.getName}"]"""
}.mkString("\n")
(Seq(header, body, s"$tab}").mkString("\n"), offset)
diff --git a/src/main/scala/firrtl/stage/package.scala b/src/main/scala/firrtl/stage/package.scala
index 89a61914..d0a481fb 100644
--- a/src/main/scala/firrtl/stage/package.scala
+++ b/src/main/scala/firrtl/stage/package.scala
@@ -49,7 +49,7 @@ package object stage {
options.collectFirst{ case a: FirrtlCircuitAnnotation => a.circuit } match {
case None => FirrtlExecutionFailure("No circuit found in AnnotationSeq!")
case Some(a) => FirrtlExecutionSuccess(
- emitType = fopts.compiler.getClass.getSimpleName,
+ emitType = fopts.compiler.getClass.getName,
emitted = emittedRes,
circuitState = CircuitState(
circuit = a,
diff --git a/src/test/scala/firrtlTests/CustomTransformSpec.scala b/src/test/scala/firrtlTests/CustomTransformSpec.scala
index 1b0e8190..e0ed6fdb 100644
--- a/src/test/scala/firrtlTests/CustomTransformSpec.scala
+++ b/src/test/scala/firrtlTests/CustomTransformSpec.scala
@@ -6,6 +6,8 @@ import firrtl.ir.Circuit
import firrtl._
import firrtl.passes.Pass
import firrtl.ir._
+import firrtl.annotations.{Annotation, NoTargetAnnotation}
+import firrtl.stage.{FirrtlSourceAnnotation, FirrtlStage, RunFirrtlTransformAnnotation}
class CustomTransformSpec extends FirrtlFlatSpec {
behavior of "Custom Transforms"
@@ -71,5 +73,28 @@ class CustomTransformSpec extends FirrtlFlatSpec {
Driver.execute(optionsManager)
}).getMessage should include (errorString)
}
-}
+ object Foo {
+ class A extends Transform {
+ def inputForm = HighForm
+ def outputForm = HighForm
+ def execute(s: CircuitState) = {
+ println(name)
+ s
+ }
+ }
+ }
+
+ they should "work if placed inside an object" in {
+ val input =
+ """|circuit Foo:
+ | module Foo:
+ | node a = UInt<1>(0)
+ |""".stripMargin
+ val annotations = Seq(
+ RunFirrtlTransformAnnotation(new Foo.A),
+ FirrtlSourceAnnotation(input)
+ )
+ (new FirrtlStage).execute(Array.empty, annotations)
+ }
+}