summaryrefslogtreecommitdiff
path: root/core/src
diff options
context:
space:
mode:
authorJack Koenig2021-04-26 15:39:54 -0700
committerGitHub2021-04-26 15:39:54 -0700
commitc71428023749b22718016f37fe68f5ddd358b5fe (patch)
tree1d6252a553431a25db80c49898c08be560e1052f /core/src
parent804271ea9bae61998811de0de42e476178ed8f75 (diff)
Add some error context to Converter .getRefs (#1878)
Diffstat (limited to 'core/src')
-rw-r--r--core/src/main/scala/chisel3/internal/firrtl/Converter.scala87
1 files changed, 51 insertions, 36 deletions
diff --git a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
index aefbf8ab..ff0fa770 100644
--- a/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
+++ b/core/src/main/scala/chisel3/internal/firrtl/Converter.scala
@@ -3,9 +3,9 @@
package chisel3.internal.firrtl
import chisel3._
import chisel3.experimental._
-import chisel3.internal.sourceinfo.{NoSourceInfo, SourceLine, SourceInfo}
+import chisel3.internal.sourceinfo.{NoSourceInfo, SourceInfo, SourceLine, UnlocatableSourceInfo}
import firrtl.{ir => fir}
-import chisel3.internal.{castToInt, throwException}
+import chisel3.internal.{HasId, castToInt, throwException}
import scala.annotation.tailrec
import scala.collection.immutable.Queue
@@ -24,6 +24,16 @@ private[chisel3] object Converter {
case Percent => ("%%", List.empty)
}
+ def getRef(id: HasId, sourceInfo: SourceInfo): Arg =
+ id.getOptionRef.getOrElse {
+ val module = id._parent.map(m => s" '$id' was defined in module '$m'.").getOrElse("")
+ val loc = sourceInfo.makeMessage(" " + _)
+ val link = "https://github.com/chipsalliance/chisel3/issues/new"
+ val msg = s"Internal error! Could not get ref for '$id'$loc!$module " +
+ s"This is a bug in Chisel, please file an issue at '$link'."
+ throwException(msg)
+ }
+
def convert(info: SourceInfo): fir.Info = info match {
case _: NoSourceInfo => fir.NoInfo
case SourceLine(fn, line, col) => fir.FileInfo(fir.StringLit(s"$fn $line:$col"))
@@ -41,37 +51,37 @@ private[chisel3] object Converter {
// TODO
// * Memoize?
// * Move into the Chisel IR?
- def convert(arg: Arg, ctx: Component): fir.Expression = arg match {
+ def convert(arg: Arg, ctx: Component, info: SourceInfo): fir.Expression = arg match {
case Node(id) =>
- convert(id.getRef, ctx)
+ convert(getRef(id, info), ctx, info)
case Ref(name) =>
fir.Reference(name, fir.UnknownType)
case Slot(imm, name) =>
- fir.SubField(convert(imm, ctx), name, fir.UnknownType)
+ fir.SubField(convert(imm, ctx, info), name, fir.UnknownType)
case Index(imm, ILit(idx)) =>
- fir.SubIndex(convert(imm, ctx), castToInt(idx, "Index"), fir.UnknownType)
+ fir.SubIndex(convert(imm, ctx, info), castToInt(idx, "Index"), fir.UnknownType)
case Index(imm, value) =>
- fir.SubAccess(convert(imm, ctx), convert(value, ctx), fir.UnknownType)
+ fir.SubAccess(convert(imm, ctx, info), convert(value, ctx, info), fir.UnknownType)
case ModuleIO(mod, name) =>
if (mod eq ctx.id) fir.Reference(name, fir.UnknownType)
- else fir.SubField(fir.Reference(mod.getRef.name, fir.UnknownType), name, fir.UnknownType)
+ else fir.SubField(fir.Reference(getRef(mod, info).name, fir.UnknownType), name, fir.UnknownType)
case u @ ULit(n, UnknownWidth()) =>
fir.UIntLiteral(n, fir.IntWidth(u.minWidth))
case ULit(n, w) =>
fir.UIntLiteral(n, convert(w))
case slit @ SLit(n, w) => fir.SIntLiteral(n, convert(w))
val unsigned = if (n < 0) (BigInt(1) << slit.width.get) + n else n
- val uint = convert(ULit(unsigned, slit.width), ctx)
+ val uint = convert(ULit(unsigned, slit.width), ctx, info)
fir.DoPrim(firrtl.PrimOps.AsSInt, Seq(uint), Seq.empty, fir.UnknownType)
// TODO Simplify
case fplit @ FPLit(n, w, bp) =>
val unsigned = if (n < 0) (BigInt(1) << fplit.width.get) + n else n
- val uint = convert(ULit(unsigned, fplit.width), ctx)
+ val uint = convert(ULit(unsigned, fplit.width), ctx, info)
val lit = bp.asInstanceOf[KnownBinaryPoint].value
fir.DoPrim(firrtl.PrimOps.AsFixedPoint, Seq(uint), Seq(lit), fir.UnknownType)
case intervalLit @ IntervalLit(n, w, bp) =>
val unsigned = if (n < 0) (BigInt(1) << intervalLit.width.get) + n else n
- val uint = convert(ULit(unsigned, intervalLit.width), ctx)
+ val uint = convert(ULit(unsigned, intervalLit.width), ctx, info)
val lit = bp.asInstanceOf[KnownBinaryPoint].value
fir.DoPrim(firrtl.PrimOps.AsInterval, Seq(uint), Seq(n, n, lit), fir.UnknownType)
case lit: ILit =>
@@ -84,7 +94,7 @@ private[chisel3] object Converter {
val consts = e.args.collect { case ILit(i) => i }
val args = e.args.flatMap {
case _: ILit => None
- case other => Some(convert(other, ctx))
+ case other => Some(convert(other, ctx, e.sourceInfo))
}
val expr = e.op.name match {
case "mux" =>
@@ -95,44 +105,45 @@ private[chisel3] object Converter {
}
Some(fir.DefNode(convert(e.sourceInfo), e.name, expr))
case e @ DefWire(info, id) =>
- Some(fir.DefWire(convert(info), e.name, extractType(id)))
+ Some(fir.DefWire(convert(info), e.name, extractType(id, info)))
case e @ DefReg(info, id, clock) =>
- Some(fir.DefRegister(convert(info), e.name, extractType(id), convert(clock, ctx),
- firrtl.Utils.zero, convert(id.getRef, ctx)))
+ Some(fir.DefRegister(convert(info), e.name, extractType(id, info), convert(clock, ctx, info),
+ firrtl.Utils.zero, convert(getRef(id, info), ctx, info)))
case e @ DefRegInit(info, id, clock, reset, init) =>
- Some(fir.DefRegister(convert(info), e.name, extractType(id), convert(clock, ctx),
- convert(reset, ctx), convert(init, ctx)))
+ Some(fir.DefRegister(convert(info), e.name, extractType(id, info), convert(clock, ctx, info),
+ convert(reset, ctx, info), convert(init, ctx, info)))
case e @ DefMemory(info, id, t, size) =>
- Some(firrtl.CDefMemory(convert(info), e.name, extractType(t), size, false))
+ Some(firrtl.CDefMemory(convert(info), e.name, extractType(t, info), size, false))
case e @ DefSeqMemory(info, id, t, size, ruw) =>
- Some(firrtl.CDefMemory(convert(info), e.name, extractType(t), size, true, ruw))
+ Some(firrtl.CDefMemory(convert(info), e.name, extractType(t, info), size, true, ruw))
case e: DefMemPort[_] =>
+ val info = e.sourceInfo
Some(firrtl.CDefMPort(convert(e.sourceInfo), e.name, fir.UnknownType,
- e.source.fullName(ctx), Seq(convert(e.index, ctx), convert(e.clock, ctx)), convert(e.dir)))
+ e.source.fullName(ctx), Seq(convert(e.index, ctx, info), convert(e.clock, ctx, info)), convert(e.dir)))
case Connect(info, loc, exp) =>
- Some(fir.Connect(convert(info), convert(loc, ctx), convert(exp, ctx)))
+ Some(fir.Connect(convert(info), convert(loc, ctx, info), convert(exp, ctx, info)))
case BulkConnect(info, loc, exp) =>
- Some(fir.PartialConnect(convert(info), convert(loc, ctx), convert(exp, ctx)))
+ Some(fir.PartialConnect(convert(info), convert(loc, ctx, info), convert(exp, ctx, info)))
case Attach(info, locs) =>
- Some(fir.Attach(convert(info), locs.map(l => convert(l, ctx))))
+ Some(fir.Attach(convert(info), locs.map(l => convert(l, ctx, info))))
case DefInvalid(info, arg) =>
- Some(fir.IsInvalid(convert(info), convert(arg, ctx)))
+ Some(fir.IsInvalid(convert(info), convert(arg, ctx, info)))
case e @ DefInstance(info, id, _) =>
Some(fir.DefInstance(convert(info), e.name, id.name))
case Stop(info, clock, ret) =>
- Some(fir.Stop(convert(info), ret, convert(clock, ctx), firrtl.Utils.one))
+ Some(fir.Stop(convert(info), ret, convert(clock, ctx, info), firrtl.Utils.one))
case Printf(info, clock, pable) =>
val (fmt, args) = unpack(pable, ctx)
Some(fir.Print(convert(info), fir.StringLit(fmt),
- args.map(a => convert(a, ctx)), convert(clock, ctx), firrtl.Utils.one))
+ args.map(a => convert(a, ctx, info)), convert(clock, ctx, info), firrtl.Utils.one))
case Verification(op, info, clk, pred, msg) =>
val firOp = op match {
case Formal.Assert => fir.Formal.Assert
case Formal.Assume => fir.Formal.Assume
case Formal.Cover => fir.Formal.Cover
}
- Some(fir.Verification(firOp, convert(info), convert(clk, ctx),
- convert(pred, ctx), firrtl.Utils.one, fir.StringLit(msg)))
+ Some(fir.Verification(firOp, convert(info), convert(clk, ctx, info),
+ convert(pred, ctx, info), firrtl.Utils.one, fir.StringLit(msg)))
case _ => None
}
@@ -173,7 +184,7 @@ private[chisel3] object Converter {
// Please see WhenFrame for more details
case None => cmds.head match {
case WhenBegin(info, pred) =>
- val when = fir.Conditionally(convert(info), convert(pred, ctx), fir.EmptyStmt, fir.EmptyStmt)
+ val when = fir.Conditionally(convert(info), convert(pred, ctx, info), fir.EmptyStmt, fir.EmptyStmt)
val frame = WhenFrame(when, acc, false)
rec(Queue.empty, frame +: scope)(cmds.tail)
case WhenEnd(info, depth, _) =>
@@ -221,7 +232,9 @@ private[chisel3] object Converter {
case d => d.specifiedDirection
}
- def extractType(data: Data, clearDir: Boolean = false): fir.Type = data match {
+ def extractType(data: Data, info: SourceInfo): fir.Type = extractType(data, false, info)
+
+ def extractType(data: Data, clearDir: Boolean, info: SourceInfo): fir.Type = data match {
case _: Clock => fir.ClockType
case _: AsyncReset => fir.AsyncResetType
case _: ResetType => fir.ResetType
@@ -231,16 +244,16 @@ private[chisel3] object Converter {
case d: FixedPoint => fir.FixedType(convert(d.width), convert(d.binaryPoint))
case d: Interval => fir.IntervalType(d.range.lowerBound, d.range.upperBound, d.range.firrtlBinaryPoint)
case d: Analog => fir.AnalogType(convert(d.width))
- case d: Vec[_] => fir.VectorType(extractType(d.sample_element, clearDir), d.length)
+ case d: Vec[_] => fir.VectorType(extractType(d.sample_element, clearDir, info), d.length)
case d: Record =>
val childClearDir = clearDir ||
d.specifiedDirection == SpecifiedDirection.Input || d.specifiedDirection == SpecifiedDirection.Output
def eltField(elt: Data): fir.Field = (childClearDir, firrtlUserDirOf(elt)) match {
- case (true, _) => fir.Field(elt.getRef.name, fir.Default, extractType(elt, true))
+ case (true, _) => fir.Field(getRef(elt, info).name, fir.Default, extractType(elt, true, info))
case (false, SpecifiedDirection.Unspecified | SpecifiedDirection.Output) =>
- fir.Field(elt.getRef.name, fir.Default, extractType(elt, false))
+ fir.Field(getRef(elt, info).name, fir.Default, extractType(elt, false, info))
case (false, SpecifiedDirection.Flip | SpecifiedDirection.Input) =>
- fir.Field(elt.getRef.name, fir.Flip, extractType(elt, false))
+ fir.Field(getRef(elt, info).name, fir.Flip, extractType(elt, false, info))
}
fir.BundleType(d.elements.toIndexedSeq.reverse.map { case (_, e) => eltField(e) })
}
@@ -251,6 +264,7 @@ private[chisel3] object Converter {
case StringParam(value) => fir.StringParam(name, fir.StringLit(value))
case RawParam(value) => fir.RawStringParam(name, value)
}
+
def convert(port: Port, topDir: SpecifiedDirection = SpecifiedDirection.Unspecified): fir.Port = {
val resolvedDir = SpecifiedDirection.fromParent(topDir, port.dir)
val dir = resolvedDir match {
@@ -261,8 +275,9 @@ private[chisel3] object Converter {
case SpecifiedDirection.Input | SpecifiedDirection.Output => true
case SpecifiedDirection.Unspecified | SpecifiedDirection.Flip => false
}
- val tpe = extractType(port.id, clearDir)
- fir.Port(fir.NoInfo, port.id.getRef.name, dir, tpe)
+ val info = UnlocatableSourceInfo // Unfortunately there is no source locator for ports ATM
+ val tpe = extractType(port.id, clearDir, info)
+ fir.Port(fir.NoInfo, getRef(port.id, info).name, dir, tpe)
}
def convert(component: Component): fir.DefModule = component match {