diff options
| author | Adam Izraelevitz | 2016-10-27 13:00:02 -0700 |
|---|---|---|
| committer | GitHub | 2016-10-27 13:00:02 -0700 |
| commit | 5b35f2d2722f72c81d2d6c507cd379be2a1476d8 (patch) | |
| tree | 78dc2db9e12c6db52fcbf222e339a37b6ebc0b72 /src/main/scala/firrtl/Annotations.scala | |
| parent | 1c61a0e7102983891d99d8e9c49e331c8a2178a6 (diff) | |
Wiring (#348)
Added wiring pass and simple test
Diffstat (limited to 'src/main/scala/firrtl/Annotations.scala')
| -rw-r--r-- | src/main/scala/firrtl/Annotations.scala | 71 |
1 files changed, 68 insertions, 3 deletions
diff --git a/src/main/scala/firrtl/Annotations.scala b/src/main/scala/firrtl/Annotations.scala index 2d76a832..d47ce67e 100644 --- a/src/main/scala/firrtl/Annotations.scala +++ b/src/main/scala/firrtl/Annotations.scala @@ -1,5 +1,7 @@ package firrtl +import firrtl.ir._ + import scala.collection.mutable import java.io.Writer @@ -38,6 +40,62 @@ import java.io.Writer * ----------|----------|----------|------------|-----------| */ object Annotations { + /** Returns true if a valid Module name */ + val SerializedModuleName = """([a-zA-Z_][a-zA-Z_0-9~!@#$%^*\-+=?/]*)""".r + def validModuleName(s: String): Boolean = s match { + case SerializedModuleName(name) => true + case _ => false + } + + /** Returns true if a valid component/subcomponent name */ + val SerializedComponentName = """([a-zA-Z_][a-zA-Z_0-9\[\]\.~!@#$%^*\-+=?/]*)""".r + def validComponentName(s: String): Boolean = s match { + case SerializedComponentName(name) => true + case _ => false + } + + /** Tokenizes a string with '[', ']', '.' as tokens, e.g.: + * "foo.bar[boo.far]" becomes Seq("foo" "." "bar" "[" "boo" "." "far" "]") + */ + def tokenize(s: String): Seq[String] = s.find(c => "[].".contains(c)) match { + case Some(_) => + val i = s.indexWhere(c => "[].".contains(c)) + Seq(s.slice(0, i), s(i).toString) ++ tokenize(s.drop(i + 1)) + case None => Seq(s) + } + + /** Given a serialized component/subcomponent reference, subindex, subaccess, + * or subfield, return the corresponding IR expression. + */ + def toExp(s: String): Expression = { + def parse(tokens: Seq[String]): Expression = { + val DecPattern = """([1-9]\d*)""".r + def findClose(tokens: Seq[String], index: Int, nOpen: Int): Seq[String] = + if(index >= tokens.size) { + error("Cannot find closing bracket ]") + } else tokens(index) match { + case "[" => findClose(tokens, index + 1, nOpen + 1) + case "]" if nOpen == 1 => tokens.slice(1, index) + case _ => findClose(tokens, index + 1, nOpen) + } + def buildup(e: Expression, tokens: Seq[String]): Expression = tokens match { + case "[" :: tail => + val indexOrAccess = findClose(tokens, 0, 0) + indexOrAccess.head match { + case DecPattern(d) => SubIndex(e, d.toInt, UnknownType) + case _ => buildup(SubAccess(e, parse(indexOrAccess), UnknownType), tokens.slice(1, indexOrAccess.size)) + } + case "." :: tail => + buildup(SubField(e, tokens(1), UnknownType), tokens.drop(2)) + case Nil => e + } + val root = Reference(tokens.head, UnknownType) + buildup(root, tokens.tail) + } + if(validComponentName(s)) { + parse(tokenize(s)) + } else error(s"Cannot convert $s into an expression.") + } case class AnnotationException(message: String) extends Exception(message) @@ -45,9 +103,16 @@ object Annotations { * Named classes associate an annotation with a component in a Firrtl circuit */ trait Named { def name: String } - case class CircuitName(name: String) extends Named - case class ModuleName(name: String, circuit: CircuitName) extends Named - case class ComponentName(name: String, module: ModuleName) extends Named + case class CircuitName(name: String) extends Named { + if(!validModuleName(name)) throw AnnotationException(s"Illegal circuit name: $name") + } + case class ModuleName(name: String, circuit: CircuitName) extends Named { + if(!validModuleName(name)) throw AnnotationException(s"Illegal module name: $name") + } + case class ComponentName(name: String, module: ModuleName) extends Named { + if(!validComponentName(name)) throw AnnotationException(s"Illegal component name: $name") + def expr: Expression = toExp(name) + } /** * Transform ID (TransID) associates an annotation with an instantiated |
