aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack2015-10-12 16:45:21 -0700
committerJack2015-10-12 16:45:21 -0700
commit0c288c48382f1b31fbfb1c202867fb444e46136c (patch)
tree6b3498b1ebae1cbd3f7298165cae631a7f6c6bd1
parentd1295b29d89e07645c3a4e08f2f923455a868482 (diff)
Added support for no width to mean unknown, and print nothing instead of <?> for unknown width. Also added test to check this
-rw-r--r--src/main/antlr4/FIRRTL.g412
-rw-r--r--src/main/scala/firrtl/IR.scala4
-rw-r--r--src/main/scala/firrtl/Utils.scala12
-rw-r--r--src/main/scala/firrtl/Visitor.scala18
-rw-r--r--test/parser/bundle.fir43
5 files changed, 69 insertions, 20 deletions
diff --git a/src/main/antlr4/FIRRTL.g4 b/src/main/antlr4/FIRRTL.g4
index 08697bb1..d9f3d18f 100644
--- a/src/main/antlr4/FIRRTL.g4
+++ b/src/main/antlr4/FIRRTL.g4
@@ -1,7 +1,3 @@
-// Jack Koenig
-// UC Berkeley ASPIRE Lab
-// July 9, 2015
-
grammar FIRRTL;
/*------------------------------------------------------------------
@@ -33,8 +29,8 @@ portKind
;
type
- : 'UInt' '<' width '>'
- | 'SInt' '<' width '>'
+ : 'UInt' ('<' width '>')?
+ | 'SInt' ('<' width '>')?
| 'Clock'
| '{' field* '}' // Bundle
| type '[' IntLit ']' // Vector
@@ -93,8 +89,8 @@ dir
// TODO implement
// What is exp?
exp
- : 'UInt' '<' width '>' '(' (IntLit) ')' // FIXME what does "ints" mean?
- | 'SInt' '<' width '>' '(' (IntLit) ')' // FIXME same
+ : '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 ']'
diff --git a/src/main/scala/firrtl/IR.scala b/src/main/scala/firrtl/IR.scala
index c52c45a4..876e8641 100644
--- a/src/main/scala/firrtl/IR.scala
+++ b/src/main/scala/firrtl/IR.scala
@@ -50,8 +50,8 @@ case object Bits extends PrimOp
// 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 UIntValue(value: BigInt, width: Width) extends Exp
+case class SIntValue(value: BigInt, width: Width) 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
diff --git a/src/main/scala/firrtl/Utils.scala b/src/main/scala/firrtl/Utils.scala
index 37cdcc71..8a7a5b0d 100644
--- a/src/main/scala/firrtl/Utils.scala
+++ b/src/main/scala/firrtl/Utils.scala
@@ -62,8 +62,8 @@ object Utils {
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 v: UIntValue => s"UInt${v.width.serialize}(${v.value.serialize})"
+ case v: SIntValue => s"SInt${v.width.serialize}(${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}]"
@@ -163,8 +163,8 @@ object Utils {
implicit class WidthUtils(w: Width) {
def serialize(): String =
w match {
- case UnknownWidth => "?"
- case w: IntWidth => w.width.toString
+ case UnknownWidth => ""
+ case w: IntWidth => s"<${w.width.toString}>"
}
}
@@ -187,8 +187,8 @@ object Utils {
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: 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}]"
}
diff --git a/src/main/scala/firrtl/Visitor.scala b/src/main/scala/firrtl/Visitor.scala
index 276facce..879ce80d 100644
--- a/src/main/scala/firrtl/Visitor.scala
+++ b/src/main/scala/firrtl/Visitor.scala
@@ -3,6 +3,7 @@
* - 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?
+ * - More elegant way to insert UnknownWidth?
*/
package firrtl
@@ -58,8 +59,10 @@ class Visitor(val fullFilename: String) extends FIRRTLBaseVisitor[AST]
// 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 "UInt" => if (ctx.getChildCount > 1) UIntType( visitWidth(ctx.width) )
+ else UIntType( UnknownWidth )
+ case "SInt" => if (ctx.getChildCount > 1) SIntType( visitWidth(ctx.width) )
+ else SIntType( UnknownWidth )
case "Clock" => ClockType
case "{" => BundleType(ctx.field.map(visitField))
case _ => new VectorType( visitType(ctx.`type`), string2BigInt(ctx.IntLit.getText) )
@@ -132,8 +135,15 @@ class Visitor(val fullFilename: String) extends FIRRTLBaseVisitor[AST]
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 "UInt" => {
+ val width = if (ctx.getChildCount > 4) visitWidth(ctx.width) else UnknownWidth
+ UIntValue(string2BigInt(ctx.IntLit(0).getText), width)
+ }
+ //case "SInt" => SIntValue(string2BigInt(ctx.IntLit(0).getText), string2BigInt(ctx.width.getText))
+ case "SInt" => {
+ val width = if (ctx.getChildCount > 4) visitWidth(ctx.width) else UnknownWidth
+ SIntValue(string2BigInt(ctx.IntLit(0).getText), width)
+ }
case _ =>
ctx.getChild(1).getText match {
case "." => new Subfield(visitExp(ctx.exp(0)), ctx.id.getText, UnknownType)
diff --git a/test/parser/bundle.fir b/test/parser/bundle.fir
new file mode 100644
index 00000000..15fa26d0
--- /dev/null
+++ b/test/parser/bundle.fir
@@ -0,0 +1,43 @@
+; RUN: firrtl -i %s -o %s.out -X HighFIRRTL && cat %s.out | FileCheck %s
+circuit top :
+ module top :
+ wire z : { x : UInt, flip y: SInt}
+ z.x := UInt(1)
+ z.y := SInt(1)
+ node x = z.x
+ node y = z.y
+ wire a : UInt<3>[10]
+ a[0] := UInt(1)
+ a[1] := UInt(1)
+ a[2] := UInt(1)
+ a[3] := UInt(1)
+ a[4] := UInt(1)
+ a[5] := UInt(1)
+ a[6] := UInt(1)
+ a[7] := UInt(1)
+ a[8] := UInt(1)
+ a[9] := UInt(1)
+ node b = a[2]
+ read accessor c = a[UInt(3)]
+
+; CHECK: circuit top :
+; CHECK: module top :
+; CHECK: wire z : { x : UInt, flip y : SInt }
+; CHECK: z.x := UInt("h01")
+; CHECK: z.y := SInt("h01")
+; CHECK: node x = z.x
+; CHECK: node y = z.y
+; CHECK: wire a : UInt<3>[10]
+; CHECK: a[0] := UInt("h01")
+; CHECK: a[1] := UInt("h01")
+; CHECK: a[2] := UInt("h01")
+; CHECK: a[3] := UInt("h01")
+; CHECK: a[4] := UInt("h01")
+; CHECK: a[5] := UInt("h01")
+; CHECK: a[6] := UInt("h01")
+; CHECK: a[7] := UInt("h01")
+; CHECK: a[8] := UInt("h01")
+; CHECK: a[9] := UInt("h01")
+; CHECK: node b = a[2]
+; CHECK: read accessor c = a[UInt("h03")]
+