diff options
| author | Jack | 2015-10-12 16:45:21 -0700 |
|---|---|---|
| committer | Jack | 2015-10-12 16:45:21 -0700 |
| commit | 0c288c48382f1b31fbfb1c202867fb444e46136c (patch) | |
| tree | 6b3498b1ebae1cbd3f7298165cae631a7f6c6bd1 | |
| parent | d1295b29d89e07645c3a4e08f2f923455a868482 (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.g4 | 12 | ||||
| -rw-r--r-- | src/main/scala/firrtl/IR.scala | 4 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Utils.scala | 12 | ||||
| -rw-r--r-- | src/main/scala/firrtl/Visitor.scala | 18 | ||||
| -rw-r--r-- | test/parser/bundle.fir | 43 |
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")] + |
