aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorazidar2015-10-06 14:28:24 -0700
committerazidar2015-10-06 14:28:24 -0700
commit2485d20374166b27c06c475a4aef365761a818f7 (patch)
tree627b3c180ba41d7619b1acc8be03e2195dd208aa
parent62e922b0e7ea5f90c14a918ab09ce04a28f082d4 (diff)
parent0a9dfbe9f58338fc8af11015f6e9227e0cb46ea4 (diff)
Merge branch 'master' of github.com:ucb-bar/firrtl
Conflicts: README.md
-rw-r--r--.gitignore15
-rw-r--r--README.md6
-rw-r--r--build.sbt14
-rw-r--r--project/sbt-antlr4.sbt3
-rw-r--r--src/main/antlr4/FIRRTL.g4207
-rw-r--r--src/main/scala/Example.scala19
-rw-r--r--src/main/scala/firrtl/IR.scala110
-rw-r--r--src/main/scala/firrtl/Parser.scala44
-rw-r--r--src/main/scala/firrtl/Translator.scala115
-rw-r--r--src/main/scala/firrtl/Utils.scala194
-rw-r--r--src/main/scala/firrtl/Visitor.scala185
-rw-r--r--src/main/stanza/compilers.stanza10
-rw-r--r--src/main/stanza/custom-compiler.stanza2
-rw-r--r--src/main/stanza/ir-utils.stanza14
-rw-r--r--src/main/stanza/passes.stanza390
-rw-r--r--src/main/stanza/verilog.stanza4
-rw-r--r--test/errors/high-form/RemoveScope.fir1
-rw-r--r--test/errors/high-form/Unique.fir1
-rw-r--r--test/features/Link.fir2
-rw-r--r--test/passes/expand-accessors/accessor-mem.fir9
-rw-r--r--test/passes/expand-accessors/accessor-vec.fir17
-rw-r--r--test/passes/expand-accessors/simple.fir15
-rw-r--r--test/passes/expand-accessors/simple2.fir17
-rw-r--r--test/passes/expand-whens/reg-and-when.fir2
-rw-r--r--test/passes/expand-whens/reg-dwoc.fir2
-rw-r--r--test/passes/expand-whens/reg-wdc.fir6
-rw-r--r--test/passes/expand-whens/reg-wdoc.fir5
-rw-r--r--test/passes/infer-types/primops.fir4
-rw-r--r--test/passes/inline-indexers/bundle-vecs.fir (renamed from test/passes/expand-connect-indexed/bundle-vecs.fir)17
-rw-r--r--test/passes/inline-indexers/init-vecs.fir (renamed from test/passes/expand-connect-indexed/init-vecs.fir)3
-rw-r--r--test/passes/inline-indexers/simple.fir20
-rw-r--r--test/passes/inline-indexers/simple2.fir26
-rw-r--r--test/passes/inline-indexers/simple3.fir20
-rw-r--r--test/passes/inline-indexers/simple4.fir25
-rw-r--r--test/passes/inline-indexers/simple5.fir21
-rw-r--r--test/passes/inline-indexers/simple6.fir45
-rw-r--r--test/passes/inline-indexers/simple7.fir13
-rw-r--r--test/passes/inline-indexers/simple8.fir240
-rw-r--r--test/passes/inline-indexers/simple9.fir18
-rw-r--r--test/passes/lower-to-ground/accessor.fir6
-rw-r--r--test/passes/lower-to-ground/bundle-vecs.fir12
-rw-r--r--test/passes/lower-to-ground/nested-vec.fir6
-rw-r--r--test/passes/split-exp/split-in-when.fir4
43 files changed, 1668 insertions, 221 deletions
diff --git a/.gitignore b/.gitignore
index ee20628e..7effd6b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,7 +29,14 @@ spec/spec.toc
spec/spec.out
spec/spec.synctex.gz
notes/*.docx
-build.sbt
-target
-project
-src/main/scala
+
+# sbt specific
+.cache
+.history
+.lib/
+dist/*
+target/
+lib_managed/
+src_managed/
+project/boot/
+project/plugins/project/
diff --git a/README.md b/README.md
index 8366ae74..dc37b048 100644
--- a/README.md
+++ b/README.md
@@ -46,3 +46,9 @@
`make check`
1. Build and test:
`make`
+
+#### Scala implementation
+The Scala FIRRTL implementation relies upon sbt.
+Example use:
+ `sbt -mem 2048 "run-main Example <input> <output>`
+This command will read in &lt;input&gt; FIRRTL file, parse it, then output the AST to &lt;output&gt;
diff --git a/build.sbt b/build.sbt
new file mode 100644
index 00000000..0a083994
--- /dev/null
+++ b/build.sbt
@@ -0,0 +1,14 @@
+lazy val root = (project in file(".")).
+ settings(
+ name := "firrtl",
+ version := "1.0",
+ scalaVersion := "2.11.4"
+ )
+
+antlr4Settings
+
+antlr4GenVisitor in Antlr4 := true // default = false
+
+antlr4GenListener in Antlr4 := false // default = true
+
+antlr4PackageName in Antlr4 := Option("firrtl.antlr")
diff --git a/project/sbt-antlr4.sbt b/project/sbt-antlr4.sbt
new file mode 100644
index 00000000..df6819fa
--- /dev/null
+++ b/project/sbt-antlr4.sbt
@@ -0,0 +1,3 @@
+resolvers += "simplytyped" at "http://simplytyped.github.io/repo/releases"
+
+addSbtPlugin("com.simplytyped" % "sbt-antlr4" % "0.7.7")
diff --git a/src/main/antlr4/FIRRTL.g4 b/src/main/antlr4/FIRRTL.g4
new file mode 100644
index 00000000..08697bb1
--- /dev/null
+++ b/src/main/antlr4/FIRRTL.g4
@@ -0,0 +1,207 @@
+// Jack Koenig
+// UC Berkeley ASPIRE Lab
+// July 9, 2015
+
+grammar FIRRTL;
+
+/*------------------------------------------------------------------
+ * PARSER RULES
+ *------------------------------------------------------------------*/
+
+// TODO add [info] support (all over the place)
+// TODO Fix connect
+// TODO Add partial connect
+// TODO Should FIRRTL keywords be legal IDs?
+
+// Does there have to be at least one module?
+circuit
+ : 'circuit' id ':' '{' module* '}'
+ ;
+
+// TODO Add support for extmodule
+module
+ : 'module' id ':' '{' port* blockStmt '}'
+ ;
+
+port
+ : portKind id ':' type
+ ;
+
+portKind
+ : 'input'
+ | 'output'
+ ;
+
+type
+ : 'UInt' '<' width '>'
+ | 'SInt' '<' width '>'
+ | 'Clock'
+ | '{' field* '}' // Bundle
+ | type '[' IntLit ']' // Vector
+ ;
+
+field
+ : orientation id ':' type
+ ;
+
+// FIXME This is what the spec says it should be
+//orientation
+// : 'default'
+// | 'reverse'
+// ;
+orientation
+ : 'flip'
+ | // Nothing
+ ;
+
+width
+ : IntLit
+ | '?'
+ ;
+
+// Much faster than replacing blockStmt with stmt+
+blockStmt
+ : (stmt)*
+ ;
+
+stmt
+ : 'wire' id ':' type
+ | 'reg' id ':' type exp exp
+ | 'smem' id ':' type exp
+ | 'cmem' id ':' type exp
+ | 'inst' id (':' | 'of') id // FIXME which should it be? ':' or 'of'
+ | 'node' id '=' exp
+ | 'poison' id ':' type // Poison, FIXME
+ | dir 'accessor' id '=' exp '[' exp ']' exp? // FIXME what is this extra exp?
+ | exp ':=' exp // Connect
+ | 'onreset' exp ':=' exp
+ | exp '<>' exp // Bulk Connect
+ | exp '[' IntLit 'through' IntLit ']' ':=' exp // SubWordConnect
+ | 'when' exp ':' '{' blockStmt '}' ( 'else' ':' '{' blockStmt '}' )?
+ | 'assert' exp
+ | 'skip'
+ ;
+
+// Accessor Direction
+dir
+ : 'infer'
+ | 'read'
+ | 'write'
+ | 'rdwr'
+ ;
+
+// TODO implement
+// What is exp?
+exp
+ : 'UInt' '<' width '>' '(' (IntLit) ')' // FIXME what does "ints" mean?
+ | 'SInt' '<' width '>' '(' (IntLit) ')' // FIXME same
+ | id // Ref
+ | exp '.' id // FIXME Does this work for no space?
+ | exp '[' IntLit ']'
+ | primop '(' exp* IntLit* ')' // FIXME Need a big check here
+ ;
+
+id
+ : Id
+ | keyword
+ ;
+
+// FIXME need to make sure this is exhaustive including all FIRRTL keywords that are legal IDs
+keyword
+ : primop
+ | dir
+ | 'inst'
+ ;
+
+primop
+ : 'add'
+ | 'sub'
+ | 'addw'
+ | 'subw'
+ | 'mul'
+ | 'div'
+ | 'mod'
+ | 'quo'
+ | 'rem'
+ | 'lt'
+ | 'leq'
+ | 'gt'
+ | 'geq'
+ | 'eq'
+ | 'neq'
+ | 'mux'
+ | 'pad'
+ | 'asUInt'
+ | 'asSInt'
+ | 'shl'
+ | 'shr'
+ | 'dshl'
+ | 'dshr'
+ | 'cvt'
+ | 'neg'
+ | 'not'
+ | 'and'
+ | 'or'
+ | 'xor'
+ | 'andr'
+ | 'orr'
+ | 'xorr'
+ | 'cat'
+ | 'bit'
+ | 'bits'
+ ;
+
+/*------------------------------------------------------------------
+ * LEXER RULES
+ *------------------------------------------------------------------*/
+
+Id
+ : IdNondigit
+ ( IdNondigit
+ | Digit
+ )*
+ ;
+
+fragment
+IdNondigit
+ : Nondigit
+ | [~!@#$%^*-+=?/]
+ ;
+
+// Should enforcing signed, non-neg, and positive ints be done in parser?
+// => YES
+IntLit
+ : '0'
+ | ( '+' | '-' )? [1-9] ( Digit )*
+ | '"' 'h' ( HexDigit )+ '"'
+ ;
+
+fragment
+Nondigit
+ : [a-zA-Z_]
+ ;
+
+fragment
+Digit
+ : [0-9]
+ ;
+
+fragment
+HexDigit
+ : [a-zA-Z0-9]
+ ;
+
+Comment
+ : ';' ~[\r\n]*
+ -> skip
+ ;
+
+Whitespace
+ : [ \t,]+
+ -> skip
+ ;
+
+Newline
+ : ( '\r'? '\n' )+
+ -> skip
+ ;
diff --git a/src/main/scala/Example.scala b/src/main/scala/Example.scala
new file mode 100644
index 00000000..210a50fb
--- /dev/null
+++ b/src/main/scala/Example.scala
@@ -0,0 +1,19 @@
+import java.io._
+import firrtl._
+import firrtl.Utils._
+
+object Example
+{
+ // Example use of Scala FIRRTL parser and serialization
+ def main(args: Array[String])
+ {
+ val inputFile = args(0)
+
+ // Parse file
+ val ast = firrtl.Parser.parse(inputFile)
+
+ val writer = new PrintWriter(new File(args(1)))
+ writer.write(ast.serialize) // serialize returns String
+ writer.close()
+ }
+}
diff --git a/src/main/scala/firrtl/IR.scala b/src/main/scala/firrtl/IR.scala
new file mode 100644
index 00000000..c52c45a4
--- /dev/null
+++ b/src/main/scala/firrtl/IR.scala
@@ -0,0 +1,110 @@
+package firrtl
+
+import scala.collection.Seq
+
+// Should this be defined elsewhere?
+case class FileInfo(file: String, line: Int, column: Int) {
+ override def toString(): String = s"$file@$line.$column"
+}
+
+trait AST
+
+trait PrimOp extends AST
+case object Add extends PrimOp
+case object Sub extends PrimOp
+case object Addw extends PrimOp
+case object Subw extends PrimOp
+case object Mul extends PrimOp
+case object Div extends PrimOp
+case object Mod extends PrimOp
+case object Quo extends PrimOp
+case object Rem extends PrimOp
+case object Lt extends PrimOp
+case object Leq extends PrimOp
+case object Gt extends PrimOp
+case object Geq extends PrimOp
+case object Eq extends PrimOp
+case object Neq extends PrimOp
+case object Mux extends PrimOp
+case object Pad extends PrimOp
+case object AsUInt extends PrimOp
+case object AsSInt extends PrimOp
+case object Shl extends PrimOp
+case object Shr extends PrimOp
+case object Dshl extends PrimOp
+case object Dshr extends PrimOp
+case object Cvt extends PrimOp
+case object Neg extends PrimOp
+case object Not extends PrimOp
+case object And extends PrimOp
+case object Or extends PrimOp
+case object Xor extends PrimOp
+case object Andr extends PrimOp
+case object Orr extends PrimOp
+case object Xorr extends PrimOp
+case object Cat extends PrimOp
+case object Bit extends PrimOp
+case object Bits extends PrimOp
+
+// TODO stanza ir has types on many of these, why? Is it the type of what we're referencing?
+// Add types, default to UNKNOWN
+// TODO add type
+trait Exp extends AST
+case class UIntValue(value: BigInt, width: BigInt) extends Exp
+case class SIntValue(value: BigInt, width: BigInt) extends Exp
+case class Ref(name: String, tpe: Type) extends Exp
+case class Subfield(exp: Exp, name: String, tpe: Type) extends Exp
+case class Subindex(exp: Exp, value: BigInt) extends Exp
+case class DoPrimOp(op: PrimOp, args: Seq[Exp], consts: Seq[BigInt]) extends Exp
+
+trait AccessorDir extends AST
+case object Infer extends AccessorDir
+case object Read extends AccessorDir
+case object Write extends AccessorDir
+case object RdWr extends AccessorDir
+
+trait Stmt extends AST
+case class DefWire(info: FileInfo, name: String, tpe: Type) extends Stmt
+case class DefReg(info: FileInfo, name: String, tpe: Type, clock: Exp, reset: Exp) extends Stmt
+case class DefMemory(info: FileInfo, name: String, seq: Boolean, tpe: Type, clock: Exp) extends Stmt
+case class DefInst(info: FileInfo, name: String, module: Exp) extends Stmt
+case class DefNode(info: FileInfo, name: String, value: Exp) extends Stmt
+case class DefPoison(info: FileInfo, name: String, tpe: Type) extends Stmt
+case class DefAccessor(info: FileInfo, name: String, dir: AccessorDir, source: Exp, index: Exp) extends Stmt
+case class OnReset(info: FileInfo, lhs: Exp, rhs: Exp) extends Stmt
+case class Connect(info: FileInfo, lhs: Exp, rhs: Exp) extends Stmt
+case class BulkConnect(info: FileInfo, lhs: Exp, rhs: Exp) extends Stmt
+case class When(info: FileInfo, pred: Exp, conseq: Stmt, alt: Stmt) extends Stmt
+case class Assert(info: FileInfo, pred: Exp) extends Stmt
+case class Block(stmts: Seq[Stmt]) extends Stmt
+case object EmptyStmt extends Stmt
+
+trait Width extends AST
+case class IntWidth(width: BigInt) extends Width
+case object UnknownWidth extends Width
+
+trait FieldDir extends AST
+case object Default extends FieldDir
+case object Reverse extends FieldDir
+
+case class Field(name: String, dir: FieldDir, tpe: Type) extends AST
+
+trait Type extends AST
+case class UIntType(width: Width) extends Type
+case class SIntType(width: Width) extends Type
+case object ClockType extends Type
+case class BundleType(fields: Seq[Field]) extends Type
+case class VectorType(tpe: Type, size: BigInt) extends Type
+case object UnknownType extends Type
+
+trait PortDir extends AST
+case object Input extends PortDir
+case object Output extends PortDir
+
+case class Port(info: FileInfo, name: String, dir: PortDir, tpe: Type) extends AST
+
+case class Module(info: FileInfo, name: String, ports: Seq[Port], stmt: Stmt) extends AST
+
+case class Circuit(info: FileInfo, name: String, modules: Seq[Module]) extends AST
+
+
diff --git a/src/main/scala/firrtl/Parser.scala b/src/main/scala/firrtl/Parser.scala
new file mode 100644
index 00000000..35e41222
--- /dev/null
+++ b/src/main/scala/firrtl/Parser.scala
@@ -0,0 +1,44 @@
+package firrtl
+
+import org.antlr.v4.runtime._;
+import org.antlr.v4.runtime.atn._;
+import org.antlr.v4.runtime.tree._;
+import java.io.FileInputStream
+import scala.collection.JavaConverters._
+import scala.io.Source
+import Utils._
+import antlr._
+
+object Parser
+{
+
+ /** Takes a firrtl filename, returns AST (root node is Circuit)
+ *
+ * Currently must be standard FIRRTL file
+ * Parser performs conversion to machine firrtl
+ */
+ def parse(filename: String): Circuit = {
+ //val antlrStream = new ANTLRInputStream(input.reader)
+ val fixedInput = Translator.addBrackets(Source.fromFile(filename).getLines)
+ val antlrStream = new ANTLRInputStream(fixedInput.result)
+ val lexer = new FIRRTLLexer(antlrStream)
+ val tokens = new CommonTokenStream(lexer)
+ val parser = new FIRRTLParser(tokens)
+
+ // FIXME Dangerous
+ parser.getInterpreter.setPredictionMode(PredictionMode.SLL)
+
+ // Concrete Syntax Tree
+ val cst = parser.circuit
+
+ val visitor = new Visitor(filename)
+ //val ast = visitor.visitCircuit(cst) match {
+ val ast = visitor.visit(cst) match {
+ case c: Circuit => c
+ case x => throw new ClassCastException("Error! AST not rooted with Circuit node!")
+ }
+
+ ast
+ }
+
+}
diff --git a/src/main/scala/firrtl/Translator.scala b/src/main/scala/firrtl/Translator.scala
new file mode 100644
index 00000000..eba78b39
--- /dev/null
+++ b/src/main/scala/firrtl/Translator.scala
@@ -0,0 +1,115 @@
+
+/* TODO
+ * - Add support for comments (that being said, current Scopers regex should ignore commented lines)
+ * - Add better error messages for illformed FIRRTL
+ * - Add support for files that do not have a circuit (like a module by itself in a file)
+ * - Improve performance? Replace regex?
+ * - Add proper commnad-line arguments?
+ * - Wrap in Reader subclass. This would have less memory footprint than creating a large string
+ */
+
+package firrtl
+
+import scala.io.Source
+import scala.collection.mutable.Stack
+import scala.collection.mutable.StringBuilder
+import java.io._
+
+
+object Translator
+{
+
+ def addBrackets(inputIt: Iterator[String]): StringBuilder = {
+ def countSpaces(s: String): Int = s.prefixLength(_ == ' ')
+
+ val Scopers = """\s*(circuit|module|when|else)(.*)""".r
+
+ // Function start
+ val it = inputIt.zipWithIndex
+ var ret = new StringBuilder()
+
+ if( !it.hasNext ) throw new Exception("Empty file!")
+
+ // Find circuit before starting scope checks
+ var line = it.next
+ while ( it.hasNext && !line._1.contains("circuit") ) {
+ ret ++= line._1 + "\n"
+ line = it.next
+ }
+ ret ++= line._1 + " { \n"
+ if( !it.hasNext ) throw new Exception("No circuit in file!")
+
+
+ val scope = Stack[Int]()
+ scope.push(countSpaces(line._1))
+ var newScope = true // indicates if increasing scope spacing is legal on next line
+
+ while( it.hasNext ) {
+ it.next match { case (text, lineNum) =>
+ val spaces = countSpaces(text)
+
+ val l = if (text.length > spaces ) { // Check that line has text in it
+ if (newScope) {
+ scope.push(countSpaces(text))
+ } else {
+
+ // Check if change in current scope
+ if( spaces < scope.top ) {
+ while( spaces < scope.top ) {
+ // Close scopes (adding brackets as we go)
+ scope.pop()
+ ret.deleteCharAt(ret.lastIndexOf("\n")) // Put on previous line
+ ret ++= " }\n"
+ }
+ if( spaces != scope.top )
+ throw new Exception("Spacing does not match scope on line : " + lineNum + " : " + scope.top)
+ }
+ else if( spaces > scope.top )
+ throw new Exception("Invalid increase in scope on line " + lineNum)
+ }
+ // Now match on legal scope increasers
+ text match {
+ case Scopers(keyword, _* ) => {
+ newScope = true
+ text + " { "
+ }
+ case _ => {
+ newScope = false
+ text
+ }
+ }
+ } // if( text.length > spaces )
+ else {
+ text // empty lines
+ }
+
+ ret ++= l + "\n"
+ } // it.next match
+ } // while( it.hasNext )
+
+ // Print any closing braces
+ while( scope.top > 0 ) {
+ scope.pop()
+ ret.deleteCharAt(ret.lastIndexOf("\n")) // Put on previous line
+ ret ++= " }\n"
+ }
+
+ ret
+ }
+
+ def main(args: Array[String]) {
+
+ try {
+ val translation = addBrackets(Source.fromFile(args(0)).getLines)
+
+ val writer = new PrintWriter(new File(args(1)))
+ writer.write(translation.result)
+ writer.close()
+ } catch {
+ case e: Exception => {
+ throw new Exception("USAGE: Translator <input file> <output file>\n" + e)
+ }
+ }
+ }
+
+}
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
new file mode 100644
index 00000000..916408bc
--- /dev/null
+++ b/src/main/scala/firrtl/Utils.scala
@@ -0,0 +1,194 @@
+// Utility functions for FIRRTL IR
+
+/* TODO
+ * - Adopt style more similar to Chisel3 Emitter?
+ */
+
+package firrtl
+
+import scala.collection.mutable.StringBuilder
+
+object Utils {
+
+ implicit class BigIntUtils(bi: BigInt){
+ def serialize(): String =
+ "\"h0" + bi.toString(16) + "\""
+ }
+
+ implicit class PrimOpUtils(op: PrimOp) {
+ def serialize(): String = {
+ op match {
+ case Add => "add"
+ case Sub => "sub"
+ case Addw => "addw"
+ case Subw => "subw"
+ case Mul => "mul"
+ case Div => "div"
+ case Mod => "mod"
+ case Quo => "quo"
+ case Rem => "rem"
+ case Lt => "lt"
+ case Leq => "leq"
+ case Gt => "gt"
+ case Geq => "geq"
+ case Eq => "eq"
+ case Neq => "neq"
+ case Mux => "mux"
+ case Pad => "pad"
+ case AsUInt => "asUInt"
+ case AsSInt => "asSInt"
+ case Shl => "shl"
+ case Shr => "shr"
+ case Dshl => "dshl"
+ case Dshr => "dshr"
+ case Cvt => "cvt"
+ case Neg => "neg"
+ case Not => "not"
+ case And => "and"
+ case Or => "or"
+ case Xor => "xor"
+ case Andr => "andr"
+ case Orr => "orr"
+ case Xorr => "xorr"
+ case Cat => "cat"
+ case Bit => "bit"
+ case Bits => "bits"
+ }
+ }
+ }
+
+ implicit class ExpUtils(exp: Exp) {
+ def serialize(): String =
+ exp match {
+ case v: UIntValue => s"UInt<${v.width}>(${v.value.serialize})"
+ case v: SIntValue => s"SInt<${v.width}>(${v.value.serialize})"
+ case r: Ref => r.name
+ case s: Subfield => s"${s.exp.serialize}.${s.name}"
+ case s: Subindex => s"${s.exp.serialize}[${s.value}]"
+ case p: DoPrimOp =>
+ s"${p.op.serialize}(" + (p.args.map(_.serialize) ++ p.consts.map(_.toString)).mkString(", ") + ")"
+ }
+ }
+
+ // AccessorDir
+ implicit class AccessorDirUtils(dir: AccessorDir) {
+ def serialize(): String =
+ dir match {
+ case Infer => "infer"
+ case Read => "read"
+ case Write => "write"
+ case RdWr => "rdwr"
+ }
+ }
+
+
+ implicit class StmtUtils(stmt: Stmt) {
+ def serialize(): String =
+ stmt match {
+ case w: DefWire => s"wire ${w.name} : ${w.tpe.serialize}"
+ case r: DefReg => s"reg ${r.name} : ${r.tpe.serialize}, ${r.clock.serialize}, ${r.reset.serialize}"
+ case m: DefMemory => (if(m.seq) "smem" else "cmem") +
+ s" ${m.name} : ${m.tpe.serialize}, ${m.clock.serialize}"
+ case i: DefInst => s"inst ${i.name} of ${i.module.serialize}"
+ case n: DefNode => s"node ${n.name} = ${n.value.serialize}"
+ case p: DefPoison => s"poison ${p.name} : ${p.tpe.serialize}"
+ case a: DefAccessor => s"${a.dir.serialize} accessor ${a.name} = ${a.source.serialize}[${a.index.serialize}]"
+ case c: Connect => s"${c.lhs.serialize} := ${c.rhs.serialize}"
+ case o: OnReset => s"onreset ${o.lhs.serialize} := ${o.rhs.serialize}"
+ case b: BulkConnect => s"${b.lhs.serialize} <> ${b.rhs.serialize}"
+ case w: When => {
+ var str = new StringBuilder(s"when ${w.pred.serialize} : ")
+ withIndent { str ++= w.conseq.serialize }
+ if( w.alt != EmptyStmt ) {
+ str ++= newline + "else :"
+ withIndent { str ++= w.alt.serialize }
+ }
+ str.result
+ }
+ //case b: Block => b.stmts.map(newline ++ _.serialize).mkString
+ case b: Block => {
+ val s = new StringBuilder
+ b.stmts.foreach { s ++= newline ++ _.serialize }
+ s.result
+ }
+ case a: Assert => s"assert ${a.pred.serialize}"
+ case EmptyStmt => "skip"
+ }
+ }
+
+ implicit class WidthUtils(w: Width) {
+ def serialize(): String =
+ w match {
+ case UnknownWidth => "?"
+ case w: IntWidth => w.width.toString
+ }
+ }
+
+ implicit class FieldDirUtils(dir: FieldDir) {
+ def serialize(): String =
+ dir match {
+ case Reverse => "flip "
+ case Default => ""
+ }
+ }
+
+ implicit class FieldUtils(field: Field) {
+ def serialize(): String =
+ s"${field.dir.serialize} ${field.name} : ${field.tpe.serialize}"
+ }
+
+ implicit class TypeUtils(t: Type) {
+ def serialize(): String = {
+ val commas = ", " // for mkString in BundleType
+ t match {
+ case ClockType => "Clock"
+ case UnknownType => "UnknownType"
+ case t: UIntType => s"UInt<${t.width.serialize}>"
+ case t: SIntType => s"SInt<${t.width.serialize}>"
+ case t: BundleType => s"{ ${t.fields.map(_.serialize).mkString(commas)} }"
+ case t: VectorType => s"${t.tpe.serialize}[${t.size}]"
+ }
+ }
+ }
+
+ implicit class PortDirUtils(p: PortDir) {
+ def serialize(): String =
+ p match {
+ case Input => "input"
+ case Output => "output"
+ }
+ }
+
+ implicit class PortUtils(p: Port) {
+ def serialize(): String =
+ s"${p.dir.serialize} ${p.name} : ${p.tpe.serialize}"
+ }
+
+ implicit class ModuleUtils(m: Module) {
+ def serialize(): String = {
+ var s = new StringBuilder(s"module ${m.name} : ")
+ withIndent {
+ s ++= m.ports.map(newline ++ _.serialize).mkString
+ s ++= newline ++ m.stmt.serialize
+ }
+ s.toString
+ }
+ }
+
+ implicit class CircuitUtils(c: Circuit) {
+ def serialize(): String = {
+ var s = new StringBuilder(s"circuit ${c.name} : ")
+ //withIndent { c.modules.foreach(s ++= newline ++ newline ++ _.serialize) }
+ withIndent { s ++= newline ++ c.modules.map(_.serialize).mkString(newline + newline) }
+ s ++= newline ++ newline
+ s.toString
+ }
+ }
+
+ private var indentLevel = 0
+ private def newline = "\n" + (" " * indentLevel)
+ private def indent(): Unit = indentLevel += 1
+ private def unindent() { require(indentLevel > 0); indentLevel -= 1 }
+ private def withIndent(f: => Unit) { indent(); f; unindent() }
+
+}
diff --git a/src/main/scala/firrtl/Visitor.scala b/src/main/scala/firrtl/Visitor.scala
new file mode 100644
index 00000000..276facce
--- /dev/null
+++ b/src/main/scala/firrtl/Visitor.scala
@@ -0,0 +1,185 @@
+/*
+ * TODO FIXME
+ * - Support all integer types (not just "h...")
+ * - In ANTLR examples they use just visit, why am I having to use visitModule or other specific functions?
+ * - Make visit private?
+*/
+
+package firrtl
+
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+import org.antlr.v4.runtime.ParserRuleContext
+import org.antlr.v4.runtime.tree.ErrorNode
+import org.antlr.v4.runtime.tree.TerminalNode
+import scala.collection.JavaConversions._
+import antlr._
+
+class Visitor(val fullFilename: String) extends FIRRTLBaseVisitor[AST]
+{
+ // Strip file path
+ private val filename = fullFilename.drop(fullFilename.lastIndexOf("/")+1)
+
+ // For some reason visitCircuit does not visit the right function
+ // FIXME for some reason this cannot be private, probably because it extends
+ // FIRRTLBaseVisitor which is in a subpackage?
+ def visit[AST](ctx: FIRRTLParser.CircuitContext): Circuit = visitCircuit(ctx)
+
+ // These regex have to change if grammar changes
+ private def string2BigInt(s: String): BigInt = {
+ // private define legal patterns
+ val HexPattern = """\"*h([a-zA-Z0-9]+)\"*""".r
+ val DecPattern = """(\+|-)?([1-9]\d*)""".r
+ val ZeroPattern = "0".r
+ s match {
+ case ZeroPattern(_*) => BigInt(0)
+ case HexPattern(hexdigits) => BigInt(hexdigits, 16)
+ case DecPattern(sign, num) => BigInt(num)
+ case _ => throw new Exception("Invalid String for conversion to BigInt " + s)
+ }
+ }
+ private def getFileInfo(ctx: ParserRuleContext): FileInfo =
+ FileInfo(filename, ctx.getStart().getLine(), ctx.getStart().getCharPositionInLine())
+
+ private def visitCircuit[AST](ctx: FIRRTLParser.CircuitContext): Circuit =
+ Circuit(getFileInfo(ctx), ctx.id.getText, ctx.module.map(visitModule))
+
+ private def visitModule[AST](ctx: FIRRTLParser.ModuleContext): Module =
+ Module(getFileInfo(ctx), ctx.id.getText, ctx.port.map(visitPort), visitBlockStmt(ctx.blockStmt))
+
+ private def visitPort[AST](ctx: FIRRTLParser.PortContext): Port =
+ Port(getFileInfo(ctx), ctx.id.getText, visitPortKind(ctx.portKind), visitType(ctx.`type`))
+
+ private def visitPortKind[AST](ctx: FIRRTLParser.PortKindContext): PortDir =
+ ctx.getText match {
+ case "input" => Input
+ case "output" => Output
+ }
+
+ // Match on a type instead of on strings?
+ private def visitType[AST](ctx: FIRRTLParser.TypeContext): Type = {
+ ctx.getChild(0).getText match {
+ case "UInt" => UIntType( visitWidth(ctx.width) )
+ case "SInt" => SIntType( visitWidth(ctx.width) )
+ case "Clock" => ClockType
+ case "{" => BundleType(ctx.field.map(visitField))
+ case _ => new VectorType( visitType(ctx.`type`), string2BigInt(ctx.IntLit.getText) )
+ }
+ }
+
+ private def visitField[AST](ctx: FIRRTLParser.FieldContext): Field =
+ Field(ctx.id.getText, visitOrientation(ctx.orientation), visitType(ctx.`type`))
+
+ private def visitOrientation[AST](ctx: FIRRTLParser.OrientationContext): FieldDir =
+ ctx.getText match {
+ case "flip" => Reverse
+ case _ => Default
+ }
+
+ private def visitWidth[AST](ctx: FIRRTLParser.WidthContext): Width = {
+ val text = ctx.getText
+ text match {
+ case "?" => UnknownWidth
+ case _ => IntWidth(string2BigInt(text))
+ }
+ }
+
+ private def visitBlockStmt[AST](ctx: FIRRTLParser.BlockStmtContext): Stmt =
+ Block(ctx.stmt.map(visitStmt))
+
+ private def visitStmt[AST](ctx: FIRRTLParser.StmtContext): Stmt = {
+ val info = getFileInfo(ctx)
+
+ ctx.getChild(0).getText match {
+ case "wire" => DefWire(info, ctx.id(0).getText, visitType(ctx.`type`))
+ case "reg" => DefReg(info, ctx.id(0).getText, visitType(ctx.`type`),
+ visitExp(ctx.exp(0)), visitExp(ctx.exp(1)))
+ case "smem" => DefMemory(info, ctx.id(0).getText, true,
+ visitType(ctx.`type`), visitExp(ctx.exp(0)))
+ case "cmem" => DefMemory(info, ctx.id(0).getText, false,
+ visitType(ctx.`type`), visitExp(ctx.exp(0)))
+ case "inst" => DefInst(info, ctx.id(0).getText, Ref(ctx.id(1).getText, UnknownType))
+ case "node" => DefNode(info, ctx.id(0).getText, visitExp(ctx.exp(0)))
+ case "poison" => DefPoison(info, ctx.id(0).getText, visitType(ctx.`type`))
+ case "onreset" => OnReset(info, visitExp(ctx.exp(0)), visitExp(ctx.exp(1)))
+ case "when" => {
+ val alt = if (ctx.blockStmt.length > 1) visitBlockStmt(ctx.blockStmt(1)) else EmptyStmt
+ When(info, visitExp(ctx.exp(0)), visitBlockStmt(ctx.blockStmt(0)), alt)
+ }
+ case "assert" => Assert(info, visitExp(ctx.exp(0)))
+ case "skip" => EmptyStmt
+ // If we don't match on the first child, try the next one
+ case _ => {
+ ctx.getChild(1).getText match {
+ case "accessor" => DefAccessor(info, ctx.id(0).getText,
+ visitDir(ctx.dir), visitExp(ctx.exp(0)), visitExp(ctx.exp(1)))
+ case ":=" => Connect(info, visitExp(ctx.exp(0)), visitExp(ctx.exp(1)) )
+ case "<>" => BulkConnect(info, visitExp(ctx.exp(0)), visitExp(ctx.exp(1)) )
+ }
+ }
+ }
+ }
+
+ private def visitDir[AST](ctx: FIRRTLParser.DirContext): AccessorDir =
+ ctx.getText match {
+ case "infer" => Infer
+ case "read" => Read
+ case "write" => Write
+ case "rdwr" => RdWr // TODO remove exceptions for unmatched things
+ }
+
+ private def visitExp[AST](ctx: FIRRTLParser.ExpContext): Exp =
+ if( ctx.getChildCount == 1 )
+ Ref(ctx.getText, UnknownType)
+ else
+ ctx.getChild(0).getText match {
+ case "UInt" => UIntValue(string2BigInt(ctx.IntLit(0).getText), string2BigInt(ctx.width.getText))
+ case "SInt" => SIntValue(string2BigInt(ctx.IntLit(0).getText), string2BigInt(ctx.width.getText))
+ case _ =>
+ ctx.getChild(1).getText match {
+ case "." => new Subfield(visitExp(ctx.exp(0)), ctx.id.getText, UnknownType)
+ case "[" => new Subindex(visitExp(ctx.exp(0)), string2BigInt(ctx.IntLit(0).getText))
+ case "(" =>
+ DoPrimOp(visitPrimop(ctx.primop), ctx.exp.map(visitExp), ctx.IntLit.map(x => string2BigInt(x.getText)))
+ }
+ }
+
+ // TODO can I create this and have the opposite? create map and invert it?
+ private def visitPrimop[AST](ctx: FIRRTLParser.PrimopContext): PrimOp =
+ ctx.getText match {
+ case "add" => Add
+ case "sub" => Sub
+ case "addw" => Addw
+ case "subw" => Subw
+ case "mul" => Mul
+ case "div" => Div
+ case "mod" => Mod
+ case "quo" => Quo
+ case "rem" => Rem
+ case "lt" => Lt
+ case "leq" => Leq
+ case "gt" => Gt
+ case "geq" => Geq
+ case "eq" => Eq
+ case "neq" => Neq
+ case "mux" => Mux
+ case "pad" => Pad
+ case "asUInt" => AsUInt
+ case "asSInt" => AsSInt
+ case "shl" => Shl
+ case "shr" => Shr
+ case "dshl" => Dshl
+ case "dshr" => Dshr
+ case "cvt" => Cvt
+ case "neg" => Neg
+ case "not" => Not
+ case "and" => And
+ case "or" => Or
+ case "xor" => Xor
+ case "andr" => Andr
+ case "orr" => Orr
+ case "xorr" => Xorr
+ case "cat" => Cat
+ case "bit" => Bit
+ case "bits" => Bits
+ }
+}
diff --git a/src/main/stanza/compilers.stanza b/src/main/stanza/compilers.stanza
index 1e978a2e..0ea9a367 100644
--- a/src/main/stanza/compilers.stanza
+++ b/src/main/stanza/compilers.stanza
@@ -25,7 +25,7 @@ public defmethod passes (c:StandardFlo) -> List<Pass> :
CheckGenders()
ExpandAccessors()
LowerToGround()
- ExpandIndexedConnects()
+ InlineIndexed()
ExpandWhens()
InferWidths()
Pad()
@@ -44,7 +44,7 @@ public defstruct StandardVerilog <: Compiler :
public defmethod passes (c:StandardVerilog) -> List<Pass> :
to-list $ [
RemoveSpecialChars() ;R
- RemoveScopes() ;R
+ ;RemoveScopes() ;R
CheckHighForm() ;R
TempElimination() ;R
ToWorkingIR() ;R -> W
@@ -56,15 +56,17 @@ public defmethod passes (c:StandardVerilog) -> List<Pass> :
CheckTypes() ;R
ExpandAccessors() ;W
LowerToGround() ;W
- ExpandIndexedConnects() ;W
+ ;ExpandIndexedConnects() ;W
+ InlineIndexed()
InferTypes() ;R
CheckGenders() ;W
ExpandWhens() ;W
InferWidths() ;R
+ ToRealIR() ;W -> R
+ CheckWidths() ;R
Pad() ;R
ConstProp() ;R
SplitExp() ;R
- ToRealIR() ;W -> R
CheckWidths() ;R
CheckHighForm() ;R
CheckLowForm() ;R
diff --git a/src/main/stanza/custom-compiler.stanza b/src/main/stanza/custom-compiler.stanza
index 36a6474f..0f43da58 100644
--- a/src/main/stanza/custom-compiler.stanza
+++ b/src/main/stanza/custom-compiler.stanza
@@ -28,7 +28,7 @@ public defmethod passes (c:InstrumentedVerilog) -> List<Pass> :
CheckGenders()
ExpandAccessors()
LowerToGround()
- ExpandIndexedConnects()
+ InlineIndexed()
InferTypes()
CheckGenders()
ExpandWhens()
diff --git a/src/main/stanza/ir-utils.stanza b/src/main/stanza/ir-utils.stanza
index a234ff81..27acedb3 100644
--- a/src/main/stanza/ir-utils.stanza
+++ b/src/main/stanza/ir-utils.stanza
@@ -9,6 +9,11 @@ public defmulti print-debug (o:OutputStream, e:Expression|Stmt|Type|Port|Field|M
;============== GENSYM STUFF ======================
+defn generated? (s:String) -> False|Int :
+ for i in 1 to length(s) - 1 find :
+ val sub = substring(s,i + 1)
+ s[i] == '_' and digits?(sub) and s[i - 1] != '_'
+
public defn firrtl-gensym (s:Symbol) -> Symbol :
firrtl-gensym(s,HashTable<Symbol,Int>(symbol-hash))
public defn firrtl-gensym (sym-hash:HashTable<Symbol,Int>) -> Symbol :
@@ -31,11 +36,11 @@ public defn firrtl-gensym (s:Symbol,sym-hash:HashTable<Symbol,Int>) -> Symbol :
sym-hash[s] = 0
s
val s* = to-string(s)
- val i* = for i in 0 to length(s*) - 1 find :
- s*[i] == '_' and digits?(substring(s*,i + 1))
- match(i*) :
+ val i* = generated?(s*)
+ val nex = match(i*) :
(i:False) : get-name(s)
(i:Int) : get-name(to-symbol(substring(s*,0,i)))
+ nex
public defn get-sym-hash (m:InModule) -> HashTable<Symbol,Int> :
get-sym-hash(m,list())
@@ -45,8 +50,7 @@ public defn get-sym-hash (m:InModule,keywords:Streamable<Symbol>) -> HashTable<S
sym-hash[k] = 0
defn add-name (s:Symbol) -> False :
val s* = to-string(s)
- val i* = for i in 0 to length(s*) - 1 find :
- s*[i] == '_' and digits?(substring(s*,i + 1))
+ val i* = generated?(s*)
match(i*) :
(i:False) :
if key?(sym-hash,s) :
diff --git a/src/main/stanza/passes.stanza b/src/main/stanza/passes.stanza
index 99fb8172..0c812535 100644
--- a/src/main/stanza/passes.stanza
+++ b/src/main/stanza/passes.stanza
@@ -21,7 +21,8 @@ public val standard-passes = to-list $ [
CheckGenders()
ExpandAccessors()
LowerToGround()
- ExpandIndexedConnects()
+ ;ExpandIndexedConnects()
+ InlineIndexed()
ExpandWhens()
InferWidths()
Inline()
@@ -67,17 +68,19 @@ public defstruct WIndex <: Expression :
type: Type with: (as-method => true)
gender: Gender with: (as-method => true)
-defstruct ConnectToIndexed <: Stmt :
+defstruct DecFromIndexer <: Stmt :
info: FileInfo with: (as-method => true)
index: Expression
- locs: List<Expression>
- exp: Expression
+ exps: List<Expression>
+ name: Symbol
+ type: Type
-defstruct ConnectFromIndexed <: Stmt :
+defstruct DecToIndexer <: Stmt :
info: FileInfo with: (as-method => true)
index: Expression
- loc: Expression
exps: List<Expression>
+ name: Symbol
+ type: Type
;================ WORKING IR UTILS =========================
@@ -259,12 +262,12 @@ defmethod print (o:OutputStream, e:WIndex) :
print-all(o,[exp(e) "[" value(e) "]"])
print-debug(o,e as ?)
-defmethod print (o:OutputStream, c:ConnectToIndexed) :
- print-all(o, [locs(c) "[" index(c) "] := " exp(c)])
+defmethod print (o:OutputStream, c:DecFromIndexer) :
+ print-all(o, ["indexer " exps(c) "[" index(c) "] = " name(c) " : " type(c)])
print-debug(o,c as ?)
-defmethod print (o:OutputStream, c:ConnectFromIndexed) :
- print-all(o, [loc(c) " := " exps(c) "[" index(c) "]" ])
+defmethod print (o:OutputStream, c:DecToIndexer) :
+ print-all(o, ["indexer " name(c) " = " exps(c) "[" index(c) "] : " type(c)])
print-debug(o,c as ?)
defmethod map (f: Expression -> Expression, e: WSubfield) :
@@ -272,10 +275,10 @@ defmethod map (f: Expression -> Expression, e: WSubfield) :
defmethod map (f: Expression -> Expression, e: WIndex) :
WIndex(f(exp(e)), value(e), type(e), gender(e))
-defmethod map (f: Expression -> Expression, c:ConnectToIndexed) :
- ConnectToIndexed(info(c),f(index(c)), map(f, locs(c)), f(exp(c)))
-defmethod map (f: Expression -> Expression, c:ConnectFromIndexed) :
- ConnectFromIndexed(info(c),f(index(c)), f(loc(c)), map(f, exps(c)))
+defmethod map (f: Expression -> Expression, c:DecFromIndexer) :
+ DecFromIndexer(info(c),f(index(c)), map(f, exps(c)), name(c), type(c))
+defmethod map (f: Expression -> Expression, c:DecToIndexer) :
+ DecToIndexer(info(c),f(index(c)), map(f, exps(c)), name(c), type(c))
defmethod map (f: Type -> Type, e: WRef) :
WRef(name(e), f(type(e)), kind(e), gender(e))
@@ -297,7 +300,7 @@ public defmethod short-name (b:RemoveSpecialChars) -> String : "rem-spec-chars"
defn get-new-string (n:Char) -> String :
switch {n == _} :
- '_' : "_"
+ '_' : "__"
'~' : "$A"
'!' : "$B"
'@' : "$C"
@@ -850,12 +853,12 @@ defn resolve-genders (c:Circuit) :
resolve-genders(m,c)
;;============== EXPAND ACCESSORS ================================
-; This pass expands non-memory accessors into ConnectToIndexed or
+; This pass expands non-memory accessors into DecFromIndexer or
; ConnectFromIndexed. All elements of the vector are
; explicitly written out, then indexed. Depending on the gender
-; of the accessor, it is transformed into ConnectToIndexed (male) or
-; ConnectFromIndexed (female)
-; Eg:
+; of the accessor, it is transformed into DecFromIndexer (male) or
+; DecToIndexer (female)
+
public defstruct ExpandAccessors <: Pass
public defmethod pass (b:ExpandAccessors) -> (Circuit -> Circuit) : expand-accessors
public defmethod name (b:ExpandAccessors) -> String : "Expand Accessors"
@@ -876,18 +879,11 @@ defn expand-stmt (s:Stmt) -> Stmt :
if mem? : s
else :
val vtype = type(type(source(s)) as VectorType)
- val wire = DefWire(info(s),name(s),vtype)
switch {acc-dir(s) == _} :
- READ : Begin{list(wire,_)} $ ConnectFromIndexed(
- info(s),
- index(s),
- WRef(name(wire),vtype,NodeKind(),FEMALE),
- expand-vector(source(s)))
- WRITE : Begin{list(wire,_)} $ ConnectToIndexed(
- info(s),
- index(s),
- expand-vector(source(s)),
- WRef(name(wire),vtype,NodeKind(),MALE))
+ READ : DecToIndexer(info(s),index(s),expand-vector(source(s)),
+ name(s), vtype)
+ WRITE : DecFromIndexer(info(s),index(s),expand-vector(source(s)),
+ name(s), vtype)
INFER : error("Shouldn't be here")
RDWR : error("Haven't implemented RDWR yet")
(s) : map(expand-stmt,s)
@@ -897,8 +893,9 @@ defn expand-accessors (c:Circuit) :
val modules* =
for m in modules(c) map :
match(m) :
- (m:InModule) : InModule(info(m),name(m),ports(m),expand-stmt(body(m)))
(m:ExModule) : m
+ (m:InModule) :
+ InModule(info(m),name(m),ports(m),expand-stmt(body(m)))
;;=============== LOWERING TO GROUND TYPES =============================
; All non-ground (elevated) types (Vectors, Bundles) are expanded out to
@@ -1091,46 +1088,31 @@ defn lower (body:Stmt) -> Stmt :
switch fn ([x,y]) : lgender == x and rgender == y :
[FEMALE,MALE] : Connect(info(s),l*,r*)
[MALE,FEMALE] : Connect(info(s),r*,l*)
- (s:ConnectFromIndexed) : Begin(ls) where :
+ (s:DecToIndexer|DecFromIndexer) : Begin(ls) where :
val ctable = HashTable<Symbol,Vector<EF>>(symbol-hash)
val index* = exp(head $ expand-expr(index(s)))
for e in exps(s) do :
- for (r in expand-expr(e),l in expand-expr(loc(s))) do :
- val n = name(exp(l) as WRef)
+ for (r in expand-expr(e), ntf in generate-entry(name(s),type(s))) do:
+ val n = name(ntf)
val x = get?(ctable,n,Vector<EF>())
add(x,r)
ctable[n] = x
- val ls = for l in expand-expr(loc(s)) map :
- val n = name(exp(l) as WRef)
- val lgender = FEMALE * flip(l)
+ val default-gender = match(s) :
+ (s:DecToIndexer) : FEMALE
+ (s:DecFromIndexer) : MALE
+ val ls = for ntf in generate-entry(name(s),type(s)) map :
+ val n = name(ntf)
+ val dec-gender = default-gender * flip(ntf)
for x in ctable[n] do :
- if (flip(x) * MALE) == lgender : error("Shouldn't be here")
- val rgender = lgender * REVERSE
- val l* = set-gender(exp(l),lgender,flip(l))
- val exps = to-list $ for e in ctable[n] map : set-gender(exp(e),rgender,flip(e))
- switch fn ([x,y]) : lgender == x and rgender == y :
- [FEMALE,MALE] : ConnectFromIndexed(info(s),index*,l*,exps)
- [MALE,FEMALE] : ConnectToIndexed(info(s),index*,exps,l*)
- (s:ConnectToIndexed) : Begin(ls) where :
- val ctable = HashTable<Symbol,Vector<EF>>(symbol-hash)
- val index* = exp(head $ expand-expr(index(s)))
- for e in locs(s) do :
- for (l in expand-expr(e),r in expand-expr(exp(s))) do :
- val n = name(exp(r) as WRef)
- val x = get?(ctable,n,Vector<EF>())
- add(x,l)
- ctable[n] = x
- val ls = for r in expand-expr(exp(s)) map :
- val n = name(exp(r) as WRef)
- val rgender = MALE * flip(r)
- for x in ctable[n] do :
- if (flip(x) * FEMALE) == rgender : error("Shouldn't be here")
- val lgender = rgender * REVERSE
- val r* = set-gender(exp(r),rgender,flip(r))
- val locs = to-list $ for e in ctable[n] map : set-gender(exp(e),lgender,flip(e))
- switch fn ([x,y]) : lgender == x and rgender == y :
- [FEMALE,MALE] : ConnectToIndexed(info(s),index*,locs,r*)
- [MALE,FEMALE] : ConnectFromIndexed(info(s),index*,r*,locs)
+ if (flip(x) * swap(default-gender)) == dec-gender :
+ error("Shouldn't be here")
+ val exps-gender = swap(dec-gender)
+ ;val l* = set-gender(exp(l),lgender,flip(ntf))
+ val exps = to-list $ for e in ctable[n] map :
+ set-gender(exp(e),exps-gender,flip(e))
+ switch fn ([x,y]) : dec-gender == x and exps-gender == y :
+ [FEMALE,MALE] : DecToIndexer(info(s),index*,exps,name(ntf),type(ntf))
+ [MALE,FEMALE] : DecFromIndexer(info(s),index*,exps,name(ntf),type(ntf))
(s:Conditionally) :
Conditionally(info(s),exp(head $ expand-expr(pred(s))),lower-stmt(conseq(s)),lower-stmt(alt(s)))
(s:Begin|EmptyStmt) : map(lower-stmt,s)
@@ -1154,66 +1136,155 @@ defn lower-to-ground (c:Circuit) -> Circuit :
;;=========== CONVERT MULTI CONNECTS to WHEN ================
-; This pass converts ConnectToIndexed and ConnectFromIndexed
+; This pass converts DecFromIndexer and DecToIndexer
; into a series of when statements. TODO what about initial
; values?
-public defstruct ExpandIndexedConnects <: Pass
-public defmethod pass (b:ExpandIndexedConnects) -> (Circuit -> Circuit) : expand-connect-indexed
-public defmethod name (b:ExpandIndexedConnects) -> String : "Expand Indexed Connects"
-public defmethod short-name (b:ExpandIndexedConnects) -> String : "expand-indexed-connects"
-
-defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
- defn equality (e1:Expression,e2:Expression) -> Expression :
- DoPrim(EQUIV-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
- defn get-name (e:Expression) -> Symbol :
- match(e) :
- (e:WRef) : name(e)
- (e:WSubfield) : symbol-join([get-name(exp(e)) `. name(e)])
- (e:WIndex) : symbol-join([get-name(exp(e)) `. to-symbol(value(e))])
- (e) : `T
- match(s) :
- (s:ConnectToIndexed) : Begin $
- if length(locs(s)) == 0 : list(EmptyStmt())
- else :
- val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
- append(
- list(DefNode(info(s),name(ref),index(s)))
- to-list $
- for (i in 0 to false, l in locs(s)) stream : Conditionally(
- info(s),
- equality(ref,UIntValue(BigIntLit(i),UnknownWidth())),
- Connect(info(s),l,exp(s)),
- EmptyStmt()
- )
- )
- (s:ConnectFromIndexed) : Begin $
- if length(exps(s)) == 0 : list(EmptyStmt())
- else :
- val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
- append(
- list(Connect(info(s),loc(s),head(exps(s))),DefNode(info(s),name(ref),index(s)))
- to-list $
- for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
- info(s),
- equality(ref,UIntValue(BigIntLit(i),UnknownWidth())),
- Connect(info(s),loc(s),e),
- EmptyStmt()
- )
- )
- (s) : map(expand-connect-indexed-stmt{_,sh},s)
-
-defn expand-connect-indexed (m: Module) -> Module :
- match(m) :
- (m:InModule) :
- val sh = get-sym-hash(m,keys(v-keywords))
- InModule(info(m),name(m),ports(m),expand-connect-indexed-stmt(body(m),sh))
- (m:ExModule) : m
+;public defstruct ExpandIndexedConnects <: Pass
+;public defmethod pass (b:ExpandIndexedConnects) -> (Circuit -> Circuit) : expand-connect-indexed
+;public defmethod name (b:ExpandIndexedConnects) -> String : "Expand Indexed Connects"
+;public defmethod short-name (b:ExpandIndexedConnects) -> String : "expand-indexed-connects"
+;
+;defn expand-connect-indexed-stmt (s: Stmt,sh:HashTable<Symbol,Int>) -> Stmt :
+; defn equality (e1:Expression,e2:Expression) -> Expression :
+; DoPrim(EQUIV-OP,list(e1,e2),List(),UIntType(UnknownWidth()))
+; defn get-name (e:Expression) -> Symbol :
+; match(e) :
+; (e:WRef) : name(e)
+; (e:WSubfield) : symbol-join([get-name(exp(e)) `. name(e)])
+; (e:WIndex) : symbol-join([get-name(exp(e)) `. to-symbol(value(e))])
+; (e) : `F
+; match(s) :
+; (s:DecFromIndexer) : Begin $
+; if length(locs(s)) == 0 : list(EmptyStmt())
+; else :
+; val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+; append(
+; list(DefNode(info(s),name(ref),index(s)))
+; to-list $
+; for (i in 0 to false, l in locs(s)) stream : Conditionally(
+; info(s),
+; equality(ref,UIntValue(BigIntLit(i),UnknownWidth())),
+; Connect(info(s),l,exp(s)),
+; EmptyStmt()
+; )
+; )
+; (s:DecToIndexer) : Begin $
+; if length(exps(s)) == 0 : list(EmptyStmt())
+; else :
+; val ref = WRef(firrtl-gensym(get-name(index(s)),sh),type(index(s)),NodeKind(),UNKNOWN-GENDER)
+; append(
+; list(Connect(info(s),loc(s),head(exps(s))),DefNode(info(s),name(ref),index(s)))
+; to-list $
+; for (i in 1 to false, e in tail(exps(s))) stream : Conditionally(
+; info(s),
+; equality(ref,UIntValue(BigIntLit(i),UnknownWidth())),
+; Connect(info(s),loc(s),e),
+; EmptyStmt()
+; )
+; )
+; (s) : map(expand-connect-indexed-stmt{_,sh},s)
+;
+;defn expand-connect-indexed (m: Module) -> Module :
+; match(m) :
+; (m:InModule) :
+; val sh = get-sym-hash(m,keys(v-keywords))
+; InModule(info(m),name(m),ports(m),expand-connect-indexed-stmt(body(m),sh))
+; (m:ExModule) : m
+;
+;defn expand-connect-indexed (c: Circuit) -> Circuit :
+; Circuit(info(c),modules*, main(c)) where :
+; val modules* =
+; for m in modules(c) map :
+; expand-connect-indexed(m)
+
+;;================ INLINE ACCESSORS =========================
+; This pass inlines all accessors to non-memory vector typed
+; components.
+
+public defstruct InlineIndexed <: Pass
+public defmethod pass (b:InlineIndexed) -> (Circuit -> Circuit) : inline-indexed
+public defmethod name (b:InlineIndexed) -> String : "Inline Indexers"
+public defmethod short-name (b:InlineIndexed) -> String : "inline-indexers"
+
+;------------ Helper Functions --------------
+defn get-name (e:Expression) -> Symbol :
+ match(e) :
+ (e:WRef) : name(e)
+ (e:WSubfield) : symbol-join([get-name(exp(e)) `. name(e)])
+ (e:WIndex) : symbol-join([get-name(exp(e)) `. to-symbol(value(e))])
+ (e) : `F
+
+defn equality (e1:Expression,i:Int) -> Expression :
+ DoPrim(EQUIV-OP,list(e1,UIntValue(BigIntLit(i),UnknownWidth())),
+ List(),UIntType(UnknownWidth()))
+
+
+;------------- Inline Accessors -------------
+
+
+
+defn inline-indexed-m (m:InModule) -> InModule :
+ val sh = get-sym-hash(m,keys(v-keywords))
+ val ih = HashTable<Symbol,Stmt>(symbol-hash)
+ defn inline-indexed-s (s:Stmt) -> Stmt :
+ val stmts = Vector<Stmt>()
+
+ defn expand-indexed (indexer:WRef,indexed-dec:Stmt) -> Expression :
+ val index = index(indexed-dec as DecFromIndexer|DecToIndexer)
+ val index-name = firrtl-gensym(get-name(index),sh)
+ val index-ref = WRef(index-name,type(index),NodeKind(),MALE)
+
+ val replace-name = firrtl-gensym(get-name(indexer),sh)
+ val replace-ref = WRef(replace-name,type(indexer),kind(indexer),gender(indexer))
+
+ add(stmts, DefWire(info(indexed-dec),name(replace-ref),type(replace-ref)))
+ add(stmts, DefNode(info(indexed-dec),index-name,index))
+ match(indexed-dec) :
+ (s:DecFromIndexer) :
+ if (gender(replace-ref) != FEMALE) : error("Shouldn't be here")
+ for (i in 0 to false, e in exps(s)) do :
+ val eq = equality(index-ref,i)
+ val cond = Conditionally(info(s),eq,Connect(info(s),e,replace-ref),EmptyStmt())
+ add(stmts,map(inline-indexed-s,cond))
+ (s:DecToIndexer) :
+ if (gender(replace-ref) != MALE) : error("Shouldn't be here")
+ val cnct = Connect(info(s),replace-ref,head(exps(s)))
+ add(stmts,map(inline-indexed-e,cnct))
+ ;println-all(["exps: " exps(s)])
+ for (i in 1 to false, e in tail(exps(s))) do :
+ val eq = equality(index-ref,i)
+ val cond = Conditionally(info(s),eq,Connect(info(s),replace-ref,e),EmptyStmt())
+ add(stmts,map(inline-indexed-s,cond))
+ replace-ref
+
+ defn inline-indexed-e (e:Expression) -> Expression :
+ match(map(inline-indexed-e,e)) :
+ (e:WRef) :
+ if key?(ih,name(e)) :
+ val indexer = ih[name(e)]
+ expand-indexed(e,indexer)
+ else : e
+ (e) : e
-defn expand-connect-indexed (c: Circuit) -> Circuit :
- Circuit(info(c),modules*, main(c)) where :
- val modules* =
- for m in modules(c) map :
- expand-connect-indexed(m)
+ match(s) :
+ (s:DecFromIndexer|DecToIndexer) :
+ ih[name(s)] = s
+ firrtl-gensym(name(s),sh)
+ add(stmts,EmptyStmt())
+ (s) :
+ val s* = map(inline-indexed-e,s)
+ add(stmts,map(inline-indexed-s,s*))
+ if length(stmts) == 1 : stmts[0]
+ else : Begin(to-list(stmts))
+
+ InModule(info(m),name(m),ports(m),inline-indexed-s(body(m)))
+
+public defn inline-indexed (c:Circuit) -> Circuit :
+ Circuit{info(c),_,main(c)} $
+ for m in modules(c) map :
+ match(m) :
+ (m:ExModule) : m
+ (m:InModule) : inline-indexed-m(m)
;;================ EXPAND WHENS =============================
; This pass does three things: remove last connect semantics,
@@ -1448,7 +1519,9 @@ defn merge-resets (assign:HashTable<Symbol,SymbolicValue>, resets:HashTable<Symb
val table = HashTable<Symbol,SymbolicValue>(symbol-hash)
for i in get-unique-keys(list(assign,resets)) do :
table[i] = match(get?(assign,i,false),get?(resets,i,false)) :
- (a:SymbolicValue,r:SymbolicValue) : SVMux(rsignals[i],r,a)
+ (a:SymbolicValue,r:SymbolicValue) :
+ if r typeof SVNul : a
+ else : SVMux(rsignals[i],r,a)
(a:SymbolicValue,r:False) : a
(a:False,r:SymbolicValue) : SVMux(rsignals[i],r,SVNul())
(a:False,r:False) : error("Shouldn't be here")
@@ -1466,8 +1539,9 @@ defn build-tables (s:Stmt,
flattn[name(s)] = true
(s:DefRegister) :
assign[name(s)] = SVNul()
- flattn[name(s)] = false
+ flattn[name(s)] = true
rsignals[name(s)] = reset(s)
+ resets[name(s)] = SVNul()
(s:DefAccessor) :
assign[name(s)] = SVNul()
flattn[name(s)] = false
@@ -1513,6 +1587,12 @@ defn build-tables (s:Stmt,
for x in assign-a do : println-debug(x)
println-debug("TABLE")
for x in assign do : println-debug(x)
+ println-debug("RESET-C")
+ for x in resets-c do : println-debug(x)
+ println-debug("RESET-A")
+ for x in resets-a do : println-debug(x)
+ println-debug("RESET")
+ for x in resets do : println-debug(x)
(s:Connect|OnReset) :
val key* = match(loc(s)) :
(e:WRef) : name(e)
@@ -2171,6 +2251,33 @@ defn inline-instances (c:Circuit) :
val top = (for m in modules(c) find : name(m) == main(c)) as InModule
Circuit(info(c),list(InModule(info(top),name(top),ports(top),inline-inst(body(top)))),main(c))
+;================= Bring to Real IR ========================
+; Returns a new Circuit with only real IR nodes.
+public defstruct ToRealIR <: Pass
+public defmethod pass (b:ToRealIR) -> (Circuit -> Circuit) : to-real-ir
+public defmethod name (b:ToRealIR) -> String : "Real IR"
+public defmethod short-name (b:ToRealIR) -> String : "real-ir"
+
+defn to-real-ir (c:Circuit) :
+ defn to-exp (e:Expression) :
+ match(map(to-exp,e)) :
+ (e:WRef) : Ref(name(e), type(e))
+ (e:WSubfield) : Subfield(exp(e),name(e),type(e))
+ (e:WIndex) : error("Shouldn't be here")
+ (e) : e
+ defn to-stmt (s:Stmt) :
+ match(map(to-exp,s)) :
+ (e:DecFromIndexer) : error("Shouldn't be here")
+ (e:DecToIndexer) : error("Shouldn't be here")
+ (e) : map(to-stmt,e)
+
+ Circuit(info(c),modules*, main(c)) where :
+ val modules* =
+ for m in modules(c) map :
+ match(m) :
+ (m:InModule) : InModule(info(m),name(m), ports(m), to-stmt(body(m)))
+ (m:ExModule) : m
+
;================= Split Expressions ========================
; Intended to only work on low firrtl
@@ -2181,7 +2288,7 @@ public defmethod short-name (b:SplitExp) -> String : "split-expressions"
defn full-name (e:Expression) -> Symbol|False :
match(e) :
- (e:WRef) : name(e)
+ (e:Ref) : name(e)
(e) : false
defn split-exp (c:Circuit) :
@@ -2195,13 +2302,13 @@ defn split-exp (c:Circuit) :
;all-same-type? = false
;if not all-same-type? :
;val n* =
- ; if n typeof False : firrtl-gensym(`T,sh)
+ ; if n typeof False : firrtl-gensym(`F,sh)
; else : firrtl-gensym(symbol-join([n as Symbol temp-delin]),sh)
val n* =
- if n typeof False : firrtl-gensym(`T,sh)
+ if n typeof False : firrtl-gensym(`F,sh)
else : firrtl-gensym(n as Symbol,sh)
add(v,DefNode(info,n*,map(split-exp-e{_,n,info},e)))
- WRef(n*,type(e),NodeKind(),UNKNOWN-GENDER)
+ Ref(n*,type(e))
;else : e
(e) : map(split-exp-e{_,n,info},e)
defn f (s:Stmt) -> False: split-exp-s(s,v,sh)
@@ -2242,33 +2349,6 @@ defn split-exp (c:Circuit) :
InModule(info(m),name(m),ports(m),Begin(to-list(v)))
(m:ExModule) : m
-;================= Bring to Real IR ========================
-; Returns a new Circuit with only real IR nodes.
-public defstruct ToRealIR <: Pass
-public defmethod pass (b:ToRealIR) -> (Circuit -> Circuit) : to-real-ir
-public defmethod name (b:ToRealIR) -> String : "Real IR"
-public defmethod short-name (b:ToRealIR) -> String : "real-ir"
-
-defn to-real-ir (c:Circuit) :
- defn to-exp (e:Expression) :
- match(map(to-exp,e)) :
- (e:WRef) : Ref(name(e), type(e))
- (e:WSubfield) : Subfield(exp(e),name(e),type(e))
- (e:WIndex) : error("Shouldn't be here")
- (e) : e
- defn to-stmt (s:Stmt) :
- match(map(to-exp,s)) :
- (e:ConnectToIndexed) : error("Shouldn't be here")
- (e:ConnectFromIndexed) : error("Shouldn't be here")
- (e) : map(to-stmt,e)
-
- Circuit(info(c),modules*, main(c)) where :
- val modules* =
- for m in modules(c) map :
- match(m) :
- (m:InModule) : InModule(info(m),name(m), ports(m), to-stmt(body(m)))
- (m:ExModule) : m
-
;================= Special Rename ========================
; Returns a new Circuit with only real IR nodes.
public defstruct SpecialRename <: Pass :
@@ -2381,7 +2461,7 @@ defn pad-widths-e (desired:Long,e:Expression) -> Expression :
else :
map(pad-widths-e{new-desired,_},e)
trim-pad(desired, e*)
- (e:WRef|WSubfield|WIndex) :
+ (e:Ref|Subfield|Index) :
trim-pad(desired, e)
(e:UIntValue) :
val i = int-width!(type(e))
diff --git a/src/main/stanza/verilog.stanza b/src/main/stanza/verilog.stanza
index c4a52d5e..1a495835 100644
--- a/src/main/stanza/verilog.stanza
+++ b/src/main/stanza/verilog.stanza
@@ -155,6 +155,10 @@ defn emit (e:Expression) -> String :
for x in tail(args(e)) do :
v = concat(v, [" ^ " emit(x)])
v
+ (e) :
+ println(["Expression:" e])
+ error("Unknown expression")
+
defn emit-module (m:InModule) :
diff --git a/test/errors/high-form/RemoveScope.fir b/test/errors/high-form/RemoveScope.fir
index 395c6492..16498fd8 100644
--- a/test/errors/high-form/RemoveScope.fir
+++ b/test/errors/high-form/RemoveScope.fir
@@ -1,4 +1,5 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+; XFAIL: *
; CHECK: Done!
circuit Top :
diff --git a/test/errors/high-form/Unique.fir b/test/errors/high-form/Unique.fir
index ea2bb881..60201b92 100644
--- a/test/errors/high-form/Unique.fir
+++ b/test/errors/high-form/Unique.fir
@@ -1,5 +1,4 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; XFAIL: *
; CHECK: Reference x does not have a unique name.
; CHECK: Reference p does not have a unique name.
diff --git a/test/features/Link.fir b/test/features/Link.fir
index 721f4727..040ac2c5 100644
--- a/test/features/Link.fir
+++ b/test/features/Link.fir
@@ -1,4 +1,4 @@
-; RUN: firrtl -i %s -m /Users/cusgadmin/code/stanza/firrtl/test/features/Queue.fir -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+; RUN: firrtl -i %s -m %S/Queue.fir -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
;CHECK: Lower To Ground
circuit Top :
module Top :
diff --git a/test/passes/expand-accessors/accessor-mem.fir b/test/passes/expand-accessors/accessor-mem.fir
index 1c055b48..6f8b63e3 100644
--- a/test/passes/expand-accessors/accessor-mem.fir
+++ b/test/passes/expand-accessors/accessor-mem.fir
@@ -8,16 +8,17 @@ circuit top :
wire i : UInt<4>
i := UInt(1)
infer accessor a = m[i] ;CHECK: read accessor a = m[i]
- infer accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
- infer accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
+ infer accessor b = a[i] ;CHECK: indexer b = (a[0] a[1])[i] : UInt<32>[2]
+ infer accessor c = b[i] ;CHECK: indexer c = (b[0] b[1])[i] : UInt<32>
wire j : UInt<32>
j := c
infer accessor x = m[i] ;CHECK: write accessor x = m[i]
- infer accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
+ infer accessor y = x[i] ;CHECK: indexer (x[0] x[1])[i] = y : UInt<32>[2]
y[0] := UInt(1)
y[1] := UInt(1)
- infer accessor z = y[i] ;CHECK: (y[0] y[1])[i] := z
+ infer accessor z = y[i] ;CHECK: indexer (y[0] y[1])[i] = z : UInt<32>
z := j
; CHECK: Finished Expand Accessors
+; CHECK: Done!
diff --git a/test/passes/expand-accessors/accessor-vec.fir b/test/passes/expand-accessors/accessor-vec.fir
index c505fbaf..96a5c74c 100644
--- a/test/passes/expand-accessors/accessor-vec.fir
+++ b/test/passes/expand-accessors/accessor-vec.fir
@@ -14,19 +14,19 @@ circuit top :
m[1][1][1] := UInt(1)
wire i : UInt
i := UInt(1)
- infer accessor a = m[i] ;CHECK: a := (m[0] m[1])[i]
- infer accessor b = a[i] ;CHECK: b := (a[0] a[1])[i]
- infer accessor c = b[i] ;CHECK: c := (b[0] b[1])[i]
+ infer accessor a = m[i] ;CHECK: indexer a = (m[0] m[1])[i] : UInt<32>[2][2]
+ infer accessor b = a[i] ;CHECK: indexer b = (a[0] a[1])[i] : UInt<32>[2]
+ infer accessor c = b[i] ;CHECK: indexer c = (b[0] b[1])[i] : UInt<32>
wire j : UInt
j := c
- infer accessor x = m[i] ;CHECK: (m[0] m[1])[i] := x
+ infer accessor x = m[i] ;CHECK: indexer (m[0] m[1])[i] = x : UInt<32>[2][2]
x[0][0] := UInt(1)
x[1][0] := UInt(1)
x[0][1] := UInt(1)
x[1][1] := UInt(1)
- infer accessor y = x[i] ;CHECK: (x[0] x[1])[i] := y
- infer accessor z = y[i] ;CHECK: (y[0] y[1])[i] := z
+ infer accessor y = x[i] ;CHECK: indexer (x[0] x[1])[i] = y : UInt<32>[2]
+ infer accessor z = y[i] ;CHECK: indexer (y[0] y[1])[i] = z : UInt<32>
y[0] := UInt(1)
y[1] := UInt(1)
z := j
@@ -34,13 +34,14 @@ circuit top :
wire p : {n : UInt<32>[2]}
p.n[0] := UInt(1)
p.n[1] := UInt(1)
- infer accessor q = p.n[i] ;CHECK: (p.n[0] p.n[1])[i] := q
+ infer accessor q = p.n[i] ;CHECK: indexer (p.n[0] p.n[1])[i] = q : UInt<32>
q := j
wire r : {m : UInt<32>}[2]
r[0].m := UInt(1)
r[1].m := UInt(1)
- infer accessor s = r[i] ;CHECK: s := (r[0] r[1])[i]
+ infer accessor s = r[i] ;CHECK: indexer s = (r[0] r[1])[i] : { m : UInt<32>}
j := s.m
; CHECK: Finished Expand Accessors
+; CHECK: Done!
diff --git a/test/passes/expand-accessors/simple.fir b/test/passes/expand-accessors/simple.fir
new file mode 100644
index 00000000..7f5a4eb8
--- /dev/null
+++ b/test/passes/expand-accessors/simple.fir
@@ -0,0 +1,15 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Expand Accessors
+circuit top :
+ module top :
+ output o : UInt
+ wire m : UInt<32>[2]
+ wire i : UInt
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ i := UInt("h1")
+ infer accessor a = m[i] ;CHECK: indexer a = (m$0 m$1)[i] : UInt<32>
+ o := a
+
+
diff --git a/test/passes/expand-accessors/simple2.fir b/test/passes/expand-accessors/simple2.fir
new file mode 100644
index 00000000..54f8a507
--- /dev/null
+++ b/test/passes/expand-accessors/simple2.fir
@@ -0,0 +1,17 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Expand Accessors
+circuit top :
+ module top :
+ output o1 : UInt
+ output o2 : UInt
+ wire m : UInt<32>[2]
+ wire i : UInt
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ i := UInt("h1")
+ infer accessor a = m[i] ;CHECK: indexer a = (m$0 m$1)[i] : UInt<32>
+ o1 := a
+ o2 := a
+
+
diff --git a/test/passes/expand-whens/reg-and-when.fir b/test/passes/expand-whens/reg-and-when.fir
index 9d23acf9..ac678b6d 100644
--- a/test/passes/expand-whens/reg-and-when.fir
+++ b/test/passes/expand-whens/reg-and-when.fir
@@ -1,5 +1,5 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p cd 2>&1 | tee %s.out ; cat %s.v | FileCheck %s
-; CHECK: out_slow_bits <= fromhost_q$deq$valid ? fromhost_q$deq$bits : tohost_q$deq$bits;
+; CHECK: out__slow__bits <= fromhost__q$deq$valid ? fromhost__q$deq$bits : tohost__q$deq$bits;
circuit Top :
module Top :
input clock : Clock
diff --git a/test/passes/expand-whens/reg-dwoc.fir b/test/passes/expand-whens/reg-dwoc.fir
index c5ea4b41..60bd43a8 100644
--- a/test/passes/expand-whens/reg-dwoc.fir
+++ b/test/passes/expand-whens/reg-dwoc.fir
@@ -1,4 +1,4 @@
-; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+; RUN: firrtl -i %s -o %s.v -X verilog -p cd 2>&1 | tee %s.out | FileCheck %s
circuit top :
module top :
input clk : Clock
diff --git a/test/passes/expand-whens/reg-wdc.fir b/test/passes/expand-whens/reg-wdc.fir
index a748dcc2..c6439860 100644
--- a/test/passes/expand-whens/reg-wdc.fir
+++ b/test/passes/expand-whens/reg-wdc.fir
@@ -1,5 +1,4 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; XFAIL: *
circuit top :
module top :
input clk : Clock
@@ -16,8 +15,9 @@ circuit top :
; CHECK: module top :
; CHECK: wire p : UInt
; CHECK: reg r : UInt, clk, reset
-; CHECK: p := UInt("h00000001")
-; CHECK-NOT: when p : r := UInt("h00000002")
+; CHECK: p := UInt("h1")
+; CHECK-NOT: when p : r := UInt("h2")
; CHECK: Finished Expand Whens
+; CHECK: Done!
diff --git a/test/passes/expand-whens/reg-wdoc.fir b/test/passes/expand-whens/reg-wdoc.fir
index 646397b8..de0bbfd6 100644
--- a/test/passes/expand-whens/reg-wdoc.fir
+++ b/test/passes/expand-whens/reg-wdoc.fir
@@ -1,5 +1,4 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; XFAIL: *
circuit top :
module top :
input clk : Clock
@@ -17,8 +16,8 @@ circuit top :
; CHECK: module top :
; CHECK: wire p : UInt
; CHECK: reg r : UInt, clk, reset
-; CHECK: p := UInt("h00000001")
-; CHECK-NOT: when p : r := mux(reset, UInt("h00000001"), UInt("h00000002"))
+; CHECK: p := UInt("h1")
+; CHECK-NOT: when p : r := mux(reset, UInt("h1"), UInt("h2"))
; CHECK: Finished Expand Whens
diff --git a/test/passes/infer-types/primops.fir b/test/passes/infer-types/primops.fir
index 94f481f7..ac057c68 100644
--- a/test/passes/infer-types/primops.fir
+++ b/test/passes/infer-types/primops.fir
@@ -157,10 +157,10 @@ circuit top :
node wnot = not(a) ;CHECK: node wnot = not(a@<t:UInt>)@<t:UInt>
node unot = not(c) ;CHECK: node unot = not(c@<t:SInt>)@<t:SInt>
- node wand_ = and(a, b) ;CHECK: node wand_ = and(a@<t:UInt>, b@<t:UInt>)@<t:UInt>
+ node WAND = and(a, b) ;CHECK: node WAND = and(a@<t:UInt>, b@<t:UInt>)@<t:UInt>
node uand = and(c, d) ;CHECK: node uand = and(c@<t:SInt>, d@<t:SInt>)@<t:SInt>
- node wor_ = or(a, b) ;CHECK: node wor_ = or(a@<t:UInt>, b@<t:UInt>)@<t:UInt>
+ node WOR = or(a, b) ;CHECK: node WOR = or(a@<t:UInt>, b@<t:UInt>)@<t:UInt>
node uor = or(c, d) ;CHECK: node uor = or(c@<t:SInt>, d@<t:SInt>)@<t:SInt>
node wxor = xor(a, b) ;CHECK: node wxor = xor(a@<t:UInt>, b@<t:UInt>)@<t:UInt>
diff --git a/test/passes/expand-connect-indexed/bundle-vecs.fir b/test/passes/inline-indexers/bundle-vecs.fir
index c41794e3..28826056 100644
--- a/test/passes/expand-connect-indexed/bundle-vecs.fir
+++ b/test/passes/inline-indexers/bundle-vecs.fir
@@ -1,6 +1,6 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; CHECK: Expand Indexed Connects
+; CHECK: Inline Indexers
circuit top :
module top :
wire i : UInt
@@ -20,16 +20,17 @@ circuit top :
infer accessor b = a[i]
- ; CHECK: wire b{{[_$]+}}x : UInt<32>
- ; CHECK: wire b{{[_$]+}}y : UInt<32>
- ; CHECK: b{{[_$]+}}x := a{{[_$]+}}0{{[_$]+}}x
+ ; CHECK: wire b{{[_$]+}}x_1 : UInt<32>
; CHECK: node i_1 = i
- ; CHECK: when eqv(i_1, UInt("h1")) : b{{[_$]+}}x := a{{[_$]+}}1{{[_$]+}}x
+ ; CHECK: b{{[_$]+}}x_1 := a{{[_$]+}}0{{[_$]+}}x
+ ; CHECK: when eqv(i_1, UInt("h1")) : b{{[_$]+}}x_1 := a{{[_$]+}}1{{[_$]+}}x
+ ; CHECK: wire b{{[_$]+}}y_1 : UInt<32>
; CHECK: node i_2 = i
- ; CHECK: when eqv(i_2, UInt("h0")) : a{{[_$]+}}0{{[_$]+}}y := b{{[_$]+}}y
- ; CHECK: when eqv(i_2, UInt("h1")) : a{{[_$]+}}1{{[_$]+}}y := b{{[_$]+}}y
+ ; CHECK: when eqv(i_2, UInt("h0")) : a{{[_$]+}}0{{[_$]+}}y := b{{[_$]+}}y_1
+ ; CHECK: when eqv(i_2, UInt("h1")) : a{{[_$]+}}1{{[_$]+}}y := b{{[_$]+}}y_1
j := b.x
b.y := UInt(1)
-; CHECK: Finished Expand Indexed Connects
+; CHECK: Finished Inline Indexers
+; CHECK: Done!
diff --git a/test/passes/expand-connect-indexed/init-vecs.fir b/test/passes/inline-indexers/init-vecs.fir
index 7d64a117..149215c3 100644
--- a/test/passes/expand-connect-indexed/init-vecs.fir
+++ b/test/passes/inline-indexers/init-vecs.fir
@@ -1,7 +1,6 @@
; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
-; XFAIL: *
-; CHECK: Expand Indexed Connects
+; CHECK: Inline Indexers
circuit top :
module top :
wire outs : UInt<32>[2][1]
diff --git a/test/passes/inline-indexers/simple.fir b/test/passes/inline-indexers/simple.fir
new file mode 100644
index 00000000..ca186e97
--- /dev/null
+++ b/test/passes/inline-indexers/simple.fir
@@ -0,0 +1,20 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ output o : UInt
+ wire m : UInt<32>[2]
+ wire i : UInt
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ i := UInt("h1")
+ infer accessor a = m[i]
+ o := a
+
+;CHECK: a_1 := m$0
+;CHECK: when eqv(i_1, UInt("h1")) : a_1 := m$1
+
+
+
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple2.fir b/test/passes/inline-indexers/simple2.fir
new file mode 100644
index 00000000..3b7d92af
--- /dev/null
+++ b/test/passes/inline-indexers/simple2.fir
@@ -0,0 +1,26 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ output o1 : UInt
+ output o2 : UInt
+ wire m : UInt<32>[2]
+ wire i : UInt
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ i := UInt("h1")
+ infer accessor a = m[i]
+ o1 := a
+ o2 := a
+
+;CHECK: wire a_1 : UInt<32>
+;CHECK: a_1 := m$0
+;CHECK: when eqv(i_1, UInt("h1")) : a_1 := m$1
+;CHECK: wire a_2 : UInt<32>
+;CHECK: a_2 := m$0
+;CHECK: when eqv(i_2, UInt("h1")) : a_2 := m$1
+
+
+
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple3.fir b/test/passes/inline-indexers/simple3.fir
new file mode 100644
index 00000000..688958a0
--- /dev/null
+++ b/test/passes/inline-indexers/simple3.fir
@@ -0,0 +1,20 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ input in : UInt<32>
+ input i : UInt<1>
+ wire m : UInt<32>[2]
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ infer accessor a = m[i]
+ a := in
+
+;CHECK: wire a_1 : UInt<32>
+;CHECK: when eqv(i_1, UInt("h0")) : m$0 := a_1
+;CHECK: when eqv(i_1, UInt("h1")) : m$1 := a_1
+
+
+
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple4.fir b/test/passes/inline-indexers/simple4.fir
new file mode 100644
index 00000000..df045456
--- /dev/null
+++ b/test/passes/inline-indexers/simple4.fir
@@ -0,0 +1,25 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ input in : {x : UInt<32>, y : UInt<32>}
+ input i : UInt<1>
+ wire m : {x : UInt<32>, y : UInt<32>}[2]
+ m[0].x := UInt("h1")
+ m[0].y := UInt("h1")
+ m[1].x := UInt("h1")
+ m[1].y := UInt("h1")
+ infer accessor a = m[i]
+ a.x := in.x
+
+;CHECK: wire a$x_1 : UInt<32>
+;CHECK: node i_1 = i
+;CHECK: when eqv(i_1, UInt("h0")) : m$0$x := a$x_1
+;CHECK: when eqv(i_1, UInt("h1")) : m$1$x := a$x_1
+;CHECK: a$x_1 := in$x
+;CHECK: Finished Inline Indexers
+;CHECK: Done!
+
+
+
diff --git a/test/passes/inline-indexers/simple5.fir b/test/passes/inline-indexers/simple5.fir
new file mode 100644
index 00000000..1da83cab
--- /dev/null
+++ b/test/passes/inline-indexers/simple5.fir
@@ -0,0 +1,21 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ output o : UInt
+ o := UInt(1)
+ wire m : UInt<32>[2]
+ wire i : UInt
+ m[0] := UInt("h1")
+ m[1] := UInt("h1")
+ i := UInt("h1")
+ when i :
+ infer accessor a = m[i]
+ o := a
+
+;CHECK: when i :
+;CHECK: a_1 := m$0
+;CHECK: when eqv(i_1, UInt("h1")) : a_1 := m$1
+;CHECK: Finished Inline Indexers
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple6.fir b/test/passes/inline-indexers/simple6.fir
new file mode 100644
index 00000000..e94efc7a
--- /dev/null
+++ b/test/passes/inline-indexers/simple6.fir
@@ -0,0 +1,45 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ input value : UInt<32>
+ input in : {x : UInt<32>, y : UInt<32>}
+ wire m :{x : UInt<32>, y : UInt<32>}[2][2]
+ wire i : UInt
+ wire j : UInt
+
+ m[0][0] := in
+ m[1][0] := in
+ m[0][1] := in
+ m[1][1] := in
+ i := UInt("h1")
+ j := UInt("h1")
+
+ write accessor a = m[i]
+ write accessor b = a[j]
+ b.x := value
+
+;CHECK: wire b$x_1 : UInt<32>
+;CHECK: node j_1 = j
+;CHECK: when eqv(j_1, UInt("h0")) :
+;CHECK: wire a$0$x_1 : UInt<32>
+;CHECK: node i_1 = i
+;CHECK: when eqv(i_1, UInt("h0")) :
+;CHECK: m$0$0$x := a$0$x_1
+;CHECK: when eqv(i_1, UInt("h1")) :
+;CHECK: m$1$0$x := a$0$x_1
+;CHECK: a$0$x_1 := b$x_1
+;CHECK: when eqv(j_1, UInt("h1")) :
+;CHECK: wire a$1$x_1 : UInt<32>
+;CHECK: node i_2 = i
+;CHECK: when eqv(i_2, UInt("h0")) :
+;CHECK: m$0$1$x := a$1$x_1
+;CHECK: when eqv(i_2, UInt("h1")) :
+;CHECK: m$1$1$x := a$1$x_1
+;CHECK: a$1$x_1 := b$x_1
+;CHECK: b$x_1 := value
+
+
+
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple7.fir b/test/passes/inline-indexers/simple7.fir
new file mode 100644
index 00000000..cc9c6231
--- /dev/null
+++ b/test/passes/inline-indexers/simple7.fir
@@ -0,0 +1,13 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ output out : UInt<64>
+ input index : UInt<1>
+ wire T_292 : UInt<64>[2]
+ T_292[0] := UInt(1)
+ T_292[1] := UInt(1)
+ infer accessor T_297 = T_292[index]
+ out := T_297
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple8.fir b/test/passes/inline-indexers/simple8.fir
new file mode 100644
index 00000000..a02395a7
--- /dev/null
+++ b/test/passes/inline-indexers/simple8.fir
@@ -0,0 +1,240 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ output resp : UInt<128>[4]
+ input write : {flip ready : UInt<1>, valid : UInt<1>, bits : {way_en : UInt<4>, addr : UInt<12>, wmask : UInt<2>, data : UInt<128>}}
+ input read : {flip ready : UInt<1>, valid : UInt<1>, bits : {way_en : UInt<4>, addr : UInt<12>}}
+ input clock : Clock
+ input reset : UInt<1>
+
+ resp[0] := UInt<1>("h00")
+ resp[1] := UInt<1>("h00")
+ resp[2] := UInt<1>("h00")
+ resp[3] := UInt<1>("h00")
+ write.ready := UInt<1>("h00")
+ read.ready := UInt<1>("h00")
+ node waddr = shr(write.bits.addr, 4)
+ node raddr = shr(read.bits.addr, 4)
+ node T_65 = bits(write.bits.way_en, 1, 0)
+ node T_66 = bits(read.bits.way_en, 1, 0)
+ wire T_75 : UInt<128>[2]
+ T_75[0] := UInt<1>("h00")
+ T_75[1] := UInt<1>("h00")
+ reg T_81 : UInt<12>, clock, reset
+ when read.valid :
+ T_81 := read.bits.addr
+ skip
+ cmem T_84 : UInt<128>[256], clock
+ node T_86 = neq(T_65, UInt<1>("h00"))
+ node T_87 = and(T_86, write.valid)
+ node T_88 = bit(write.bits.wmask, 0)
+ node T_89 = and(T_87, T_88)
+ when T_89 :
+ node T_90 = bits(write.bits.data, 63, 0)
+ node T_91 = cat(T_90, T_90)
+ node T_92 = bit(T_65, 0)
+ node T_93 = bit(T_65, 1)
+ wire T_95 : UInt<1>[2]
+ T_95[0] := T_92
+ T_95[1] := T_93
+ node T_100 = subw(UInt<64>("h00"), T_95[0])
+ node T_102 = subw(UInt<64>("h00"), T_95[1])
+ wire T_104 : UInt<64>[2]
+ T_104[0] := T_100
+ T_104[1] := T_102
+ node T_108 = cat(T_104[1], T_104[0])
+ infer accessor T_109 = T_84[waddr]
+ node T_110 = not(T_108)
+ node T_111 = and(T_109, T_110)
+ node T_112 = and(T_91, T_108)
+ node T_113 = or(T_111, T_112)
+ wire T_114 : UInt<128>
+ T_114 := UInt<1>("h00")
+ T_114 := T_113
+ infer accessor T_116 = T_84[waddr]
+ T_116 := T_114
+ skip
+ node T_118 = neq(T_66, UInt<1>("h00"))
+ node T_119 = and(T_118, read.valid)
+ reg T_120 : UInt<8>, clock, reset
+ when T_119 :
+ T_120 := raddr
+ skip
+ infer accessor T_121 = T_84[T_120]
+ T_75[0] := T_121
+ cmem T_124 : UInt<128>[256], clock
+ node T_126 = neq(T_65, UInt<1>("h00"))
+ node T_127 = and(T_126, write.valid)
+ node T_128 = bit(write.bits.wmask, 1)
+ node T_129 = and(T_127, T_128)
+ when T_129 :
+ node T_130 = bits(write.bits.data, 127, 64)
+ node T_131 = cat(T_130, T_130)
+ node T_132 = bit(T_65, 0)
+ node T_133 = bit(T_65, 1)
+ wire T_135 : UInt<1>[2]
+ T_135[0] := T_132
+ T_135[1] := T_133
+ node T_140 = subw(UInt<64>("h00"), T_135[0])
+ node T_142 = subw(UInt<64>("h00"), T_135[1])
+ wire T_144 : UInt<64>[2]
+ T_144[0] := T_140
+ T_144[1] := T_142
+ node T_148 = cat(T_144[1], T_144[0])
+ infer accessor T_149 = T_124[waddr]
+ node T_150 = not(T_148)
+ node T_151 = and(T_149, T_150)
+ node T_152 = and(T_131, T_148)
+ node T_153 = or(T_151, T_152)
+ wire T_154 : UInt<128>
+ T_154 := UInt<1>("h00")
+ T_154 := T_153
+ infer accessor T_156 = T_124[waddr]
+ T_156 := T_154
+ skip
+ node T_158 = neq(T_66, UInt<1>("h00"))
+ node T_159 = and(T_158, read.valid)
+ reg T_160 : UInt<8>, clock, reset
+ when T_159 :
+ T_160 := raddr
+ skip
+ infer accessor T_161 = T_124[T_160]
+ T_75[1] := T_161
+ node T_162 = bits(T_75[0], 63, 0)
+ node T_163 = bits(T_75[1], 63, 0)
+ wire T_165 : UInt<64>[2]
+ T_165[0] := T_162
+ T_165[1] := T_163
+ node T_169 = bits(T_81, 3, 3)
+ infer accessor T_170 = T_165[T_169]
+ wire T_172 : UInt<64>[2]
+ T_172[0] := T_170
+ T_172[1] := T_165[1]
+ node T_176 = cat(T_172[1], T_172[0])
+ resp[0] := T_176
+ node T_177 = bits(T_75[0], 127, 64)
+ node T_178 = bits(T_75[1], 127, 64)
+ wire T_180 : UInt<64>[2]
+ T_180[0] := T_177
+ T_180[1] := T_178
+ node T_184 = bits(T_81, 3, 3)
+ infer accessor T_185 = T_180[T_184]
+ wire T_187 : UInt<64>[2]
+ T_187[0] := T_185
+ T_187[1] := T_180[1]
+ node T_191 = cat(T_187[1], T_187[0])
+ resp[1] := T_191
+ node T_192 = bits(write.bits.way_en, 3, 2)
+ node T_193 = bits(read.bits.way_en, 3, 2)
+ wire T_202 : UInt<128>[2]
+ T_202[0] := UInt<1>("h00")
+ T_202[1] := UInt<1>("h00")
+ reg T_208 : UInt<12>, clock, reset
+ when read.valid :
+ T_208 := read.bits.addr
+ skip
+ cmem T_211 : UInt<128>[256], clock
+ node T_213 = neq(T_192, UInt<1>("h00"))
+ node T_214 = and(T_213, write.valid)
+ node T_215 = bit(write.bits.wmask, 0)
+ node T_216 = and(T_214, T_215)
+ when T_216 :
+ node T_217 = bits(write.bits.data, 63, 0)
+ node T_218 = cat(T_217, T_217)
+ node T_219 = bit(T_192, 0)
+ node T_220 = bit(T_192, 1)
+ wire T_222 : UInt<1>[2]
+ T_222[0] := T_219
+ T_222[1] := T_220
+ node T_227 = subw(UInt<64>("h00"), T_222[0])
+ node T_229 = subw(UInt<64>("h00"), T_222[1])
+ wire T_231 : UInt<64>[2]
+ T_231[0] := T_227
+ T_231[1] := T_229
+ node T_235 = cat(T_231[1], T_231[0])
+ infer accessor T_236 = T_211[waddr]
+ node T_237 = not(T_235)
+ node T_238 = and(T_236, T_237)
+ node T_239 = and(T_218, T_235)
+ node T_240 = or(T_238, T_239)
+ wire T_241 : UInt<128>
+ T_241 := UInt<1>("h00")
+ T_241 := T_240
+ infer accessor T_243 = T_211[waddr]
+ T_243 := T_241
+ skip
+ node T_245 = neq(T_193, UInt<1>("h00"))
+ node T_246 = and(T_245, read.valid)
+ reg T_247 : UInt<8>, clock, reset
+ when T_246 :
+ T_247 := raddr
+ skip
+ infer accessor T_248 = T_211[T_247]
+ T_202[0] := T_248
+ cmem T_251 : UInt<128>[256], clock
+ node T_253 = neq(T_192, UInt<1>("h00"))
+ node T_254 = and(T_253, write.valid)
+ node T_255 = bit(write.bits.wmask, 1)
+ node T_256 = and(T_254, T_255)
+ when T_256 :
+ node T_257 = bits(write.bits.data, 127, 64)
+ node T_258 = cat(T_257, T_257)
+ node T_259 = bit(T_192, 0)
+ node T_260 = bit(T_192, 1)
+ wire T_262 : UInt<1>[2]
+ T_262[0] := T_259
+ T_262[1] := T_260
+ node T_267 = subw(UInt<64>("h00"), T_262[0])
+ node T_269 = subw(UInt<64>("h00"), T_262[1])
+ wire T_271 : UInt<64>[2]
+ T_271[0] := T_267
+ T_271[1] := T_269
+ node T_275 = cat(T_271[1], T_271[0])
+ infer accessor T_276 = T_251[waddr]
+ node T_277 = not(T_275)
+ node T_278 = and(T_276, T_277)
+ node T_279 = and(T_258, T_275)
+ node T_280 = or(T_278, T_279)
+ wire T_281 : UInt<128>
+ T_281 := UInt<1>("h00")
+ T_281 := T_280
+ infer accessor T_283 = T_251[waddr]
+ T_283 := T_281
+ skip
+ node T_285 = neq(T_193, UInt<1>("h00"))
+ node T_286 = and(T_285, read.valid)
+ reg T_287 : UInt<8>, clock, reset
+ when T_286 :
+ T_287 := raddr
+ skip
+ infer accessor T_288 = T_251[T_287]
+ T_202[1] := T_288
+ node T_289 = bits(T_202[0], 63, 0)
+ node T_290 = bits(T_202[1], 63, 0)
+ wire T_292 : UInt<64>[2]
+ T_292[0] := T_289
+ T_292[1] := T_290
+ node T_296 = bits(T_208, 3, 3)
+ infer accessor T_297 = T_292[T_296]
+ wire T_299 : UInt<64>[2]
+ T_299[0] := T_297
+ T_299[1] := T_292[1]
+ node T_303 = cat(T_299[1], T_299[0])
+ resp[2] := T_303
+ node T_304 = bits(T_202[0], 127, 64)
+ node T_305 = bits(T_202[1], 127, 64)
+ wire T_307 : UInt<64>[2]
+ T_307[0] := T_304
+ T_307[1] := T_305
+ node T_311 = bits(T_208, 3, 3)
+ infer accessor T_312 = T_307[T_311]
+ wire T_314 : UInt<64>[2]
+ T_314[0] := T_312
+ T_314[1] := T_307[1]
+ node T_318 = cat(T_314[1], T_314[0])
+ resp[3] := T_318
+ read.ready := UInt<1>("h01")
+ write.ready := UInt<1>("h01")
+;CHECK: Done!
diff --git a/test/passes/inline-indexers/simple9.fir b/test/passes/inline-indexers/simple9.fir
new file mode 100644
index 00000000..a40abb17
--- /dev/null
+++ b/test/passes/inline-indexers/simple9.fir
@@ -0,0 +1,18 @@
+; RUN: firrtl -i %s -o %s.v -X verilog -p c 2>&1 | tee %s.out | FileCheck %s
+
+;CHECK: Inline Indexers
+circuit top :
+ module top :
+ input T_4910 : UInt<1>
+ input T_4581 : UInt<1>
+ input reset : UInt<1>
+ input clock : Clock
+ output out : UInt<1>
+ reg T_4590 : UInt<1>[2], clock, reset
+ T_4590[0] := UInt(0)
+ T_4590[1] := UInt(0)
+ out := UInt(0)
+ when T_4910 :
+ infer accessor T_4911 = T_4590[T_4581]
+ out := T_4911
+;CHECK: Done!
diff --git a/test/passes/lower-to-ground/accessor.fir b/test/passes/lower-to-ground/accessor.fir
index fd261e1e..4d55d0f6 100644
--- a/test/passes/lower-to-ground/accessor.fir
+++ b/test/passes/lower-to-ground/accessor.fir
@@ -14,13 +14,11 @@ circuit top :
; CHECK: wire a{{[_$]+}}3 : UInt<32>
infer accessor b = a[i]
- ; CHECK: wire b : UInt<32>
- ; CHECK: b := (a{{[_$]+}}0 a{{[_$]+}}1 a{{[_$]+}}2 a{{[_$]+}}3)[i]
+ ; CHECK: indexer b = (a{{[_$]+}}0 a{{[_$]+}}1 a{{[_$]+}}2 a{{[_$]+}}3)[i] : UInt<32>
j := b
infer accessor c = a[i]
- ; CHECK: wire c : UInt<32>
- ; CHECK: (a{{[_$]+}}0 a{{[_$]+}}1 a{{[_$]+}}2 a{{[_$]+}}3)[i] := c
+ ; CHECK: indexer (a{{[_$]+}}0 a{{[_$]+}}1 a{{[_$]+}}2 a{{[_$]+}}3)[i] = c : UInt<32>
c := j
cmem p : UInt<32>[4],clk
diff --git a/test/passes/lower-to-ground/bundle-vecs.fir b/test/passes/lower-to-ground/bundle-vecs.fir
index 17927aef..7d37e65c 100644
--- a/test/passes/lower-to-ground/bundle-vecs.fir
+++ b/test/passes/lower-to-ground/bundle-vecs.fir
@@ -13,17 +13,13 @@ circuit top :
; CHECK: wire a{{[_$]+}}1{{[_$]+}}y : UInt<32>
infer accessor b = a[i]
- ; CHECK: wire b{{[_$]+}}x : UInt<32>
- ; CHECK: wire b{{[_$]+}}y : UInt<32>
- ; CHECK: b{{[_$]+}}x := (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i]
- ; CHECK: (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i] := b{{[_$]+}}y
+ ; CHECK: indexer b{{[_$]+}}x = (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i] : UInt<32>
+ ; CHECK: indexer (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i] = b{{[_$]+}}y : UInt<32>
j := b
infer accessor c = a[i]
- ; CHECK: wire c{{[_$]+}}x : UInt<32>
- ; CHECK: wire c{{[_$]+}}y : UInt<32>
- ; CHECK: (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i] := c{{[_$]+}}x
- ; CHECK: c{{[_$]+}}y := (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i]
+ ; CHECK: indexer (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i] = c{{[_$]+}}x : UInt<32>
+ ; CHECK: indexer c{{[_$]+}}y = (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i] : UInt<32>
c := j
diff --git a/test/passes/lower-to-ground/nested-vec.fir b/test/passes/lower-to-ground/nested-vec.fir
index d484a6dc..aa208b01 100644
--- a/test/passes/lower-to-ground/nested-vec.fir
+++ b/test/passes/lower-to-ground/nested-vec.fir
@@ -15,10 +15,8 @@ circuit top :
; CHECK: wire a{{[_$]+}}1{{[_$]+}}y : UInt<32>
infer accessor b = a[i]
- ; CHECK: wire b{{[_$]+}}x : UInt<32>
- ; CHECK: wire b{{[_$]+}}y : UInt<32>
- ; CHECK: b{{[_$]+}}x := (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i]
- ; CHECK: (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i] := b{{[_$]+}}y
+ ; CHECK: indexer b{{[_$]+}}x = (a{{[_$]+}}0{{[_$]+}}x a{{[_$]+}}1{{[_$]+}}x)[i] : UInt<32>
+ ; CHECK: indexer (a{{[_$]+}}0{{[_$]+}}y a{{[_$]+}}1{{[_$]+}}y)[i] = b{{[_$]+}}y : UInt<32>
j := b
cmem m : { x : UInt<32>, y : UInt<32> }[2],clk
diff --git a/test/passes/split-exp/split-in-when.fir b/test/passes/split-exp/split-in-when.fir
index ddf6a155..58819d22 100644
--- a/test/passes/split-exp/split-in-when.fir
+++ b/test/passes/split-exp/split-in-when.fir
@@ -13,11 +13,11 @@ circuit Top :
when bit(subw(a,c),3) : out := mux(eqv(bits(UInt(32),4,0),UInt(13)),addw(a,addw(b,c)),subw(c,b))
-;CHECK: node T = subw(a, c)
+;CHECK: node F = subw(a, c)
;CHECK: node out_1 = eqv(UInt("h0"), UInt("hd"))
;CHECK: node out_3 = addw(b, c)
;CHECK: node out_2 = addw(a, out_3)
;CHECK: node out_4 = subw(c, b)
-;CHECK: when bit(T, 3) : out := mux(out_1, out_2, out_4)
+;CHECK: when bit(F, 3) : out := mux(out_1, out_2, out_4)
;CHECK: Finished Split Expressions