From d408d73a171535bd7c2ba9d0037c194022b8a62f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 20 Jun 2016 11:08:46 -0700 Subject: Rename chisel3 package. --- .../src/main/scala/chisel3/internal/Builder.scala | 129 ++++++++++++++ .../src/main/scala/chisel3/internal/Error.scala | 91 ++++++++++ .../main/scala/chisel3/internal/SourceInfo.scala | 51 ++++++ .../main/scala/chisel3/internal/firrtl/IR.scala | 190 +++++++++++++++++++++ 4 files changed, 461 insertions(+) create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/Builder.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/Error.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala new file mode 100644 index 00000000..01628105 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -0,0 +1,129 @@ +// See LICENSE for license details. + +package chisel.internal + +import scala.util.DynamicVariable +import scala.collection.mutable.{ArrayBuffer, HashMap} + +import chisel._ +import core._ +import firrtl._ + +private[chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) { + private val names = collection.mutable.HashMap[String, Long]() + for (keyword <- keywords) + names(keyword) = 1 + + private def rename(n: String): String = { + val index = names.getOrElse(n, 1L) + val tryName = s"${n}_${index}" + names(n) = index + 1 + if (this contains tryName) rename(n) else tryName + } + + def contains(elem: String): Boolean = { + names.contains(elem) || parent.map(_ contains elem).getOrElse(false) + } + + def name(elem: String): String = { + if (this contains elem) { + name(rename(elem)) + } else { + names(elem) = 1 + elem + } + } + + def child(kws: Set[String]): Namespace = new Namespace(Some(this), kws) + def child: Namespace = child(Set()) +} + +private[chisel] class IdGen { + private var counter = -1L + def next: Long = { + counter += 1 + counter + } +} + +private[chisel] trait HasId { + private[chisel] def _onModuleClose {} // scalastyle:ignore method.name + private[chisel] val _parent = Builder.dynamicContext.currentModule + _parent.foreach(_.addId(this)) + + private[chisel] val _id = Builder.idGen.next + override def hashCode: Int = _id.toInt + override def equals(that: Any): Boolean = that match { + case x: HasId => _id == x._id + case _ => false + } + + // Facilities for 'suggesting' a name to this. + // Post-name hooks called to carry the suggestion to other candidates as needed + private var suggested_name: Option[String] = None + private val postname_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit] + // Only takes the first suggestion! + def suggestName(name: =>String): this.type = { + if(suggested_name.isEmpty) suggested_name = Some(name) + for(hook <- postname_hooks) { hook(name) } + this + } + private[chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook + + // Uses a namespace to convert suggestion into a true name + // Will not do any naming if the reference already assigned. + // (e.g. tried to suggest a name to part of a Bundle) + private[chisel] def forceName(default: =>String, namespace: Namespace): Unit = + if(_ref.isEmpty) { + val candidate_name = suggested_name.getOrElse(default) + val available_name = namespace.name(candidate_name) + setRef(Ref(available_name)) + } + + private var _ref: Option[Arg] = None + private[chisel] def setRef(imm: Arg): Unit = _ref = Some(imm) + private[chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) + private[chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) + private[chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) + private[chisel] def getRef: Arg = _ref.get +} + +private[chisel] class DynamicContext { + val idGen = new IdGen + val globalNamespace = new Namespace(None, Set()) + val components = ArrayBuffer[Component]() + var currentModule: Option[Module] = None + val errors = new ErrorLog +} + +private[chisel] object Builder { + // All global mutable state must be referenced via dynamicContextVar!! + private val dynamicContextVar = new DynamicVariable[Option[DynamicContext]](None) + + def dynamicContext: DynamicContext = + dynamicContextVar.value getOrElse (new DynamicContext) + def idGen: IdGen = dynamicContext.idGen + def globalNamespace: Namespace = dynamicContext.globalNamespace + def components: ArrayBuffer[Component] = dynamicContext.components + + def pushCommand[T <: Command](c: T): T = { + dynamicContext.currentModule.foreach(_._commands += c) + c + } + def pushOp[T <: Data](cmd: DefPrim[T]): T = pushCommand(cmd).id + + def errors: ErrorLog = dynamicContext.errors + def error(m: => String): Unit = errors.error(m) + + def build[T <: Module](f: => T): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext)) { + errors.info("Elaborating design...") + val mod = f + mod.forceName(mod.name, globalNamespace) + errors.checkpoint() + errors.info("Done elaborating.") + + Circuit(components.last.name, components) + } + } +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala new file mode 100644 index 00000000..f0481dc4 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -0,0 +1,91 @@ +// See LICENSE for license details. + +package chisel.internal + +import scala.collection.mutable.ArrayBuffer + +import chisel.core._ + +class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) + +private[chisel] object throwException { + def apply(s: String, t: Throwable = null): Nothing = + throw new ChiselException(s, t) +} + +/** Records and reports runtime errors and warnings. */ +private[chisel] class ErrorLog { + def hasErrors: Boolean = errors.exists(_.isFatal) + + /** Log an error message */ + def error(m: => String): Unit = + errors += new Error(m, getUserLineNumber) + + /** Log a warning message */ + def warning(m: => String): Unit = + errors += new Warning(m, getUserLineNumber) + + /** Emit an informational message */ + def info(m: String): Unit = + println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) // scalastyle:ignore regex + + /** Prints error messages generated by Chisel at runtime. */ + def report(): Unit = errors foreach println // scalastyle:ignore regex + + /** Throw an exception if any errors have yet occurred. */ + def checkpoint(): Unit = if(hasErrors) { + import Console._ + throwException(errors.map(_ + "\n").reduce(_ + _) + + UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET + + UNDERLINED + " " + RED + "ERRORS" + RESET + + UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET + + UNDERLINED + " " + YELLOW + "WARNINGS" + RESET) + } + + private def findFirstUserFrame(stack: Array[StackTraceElement]): Option[StackTraceElement] = { + def isUserCode(ste: StackTraceElement): Boolean = { + def isUserModule(c: Class[_]): Boolean = + c != null && (c == classOf[Module] || isUserModule(c.getSuperclass)) + isUserModule(Class.forName(ste.getClassName)) + } + + stack.indexWhere(isUserCode) match { + case x if x < 0 => None + case x => Some(stack(x)) + } + } + + private def getUserLineNumber = + findFirstUserFrame(Thread.currentThread().getStackTrace) + + private val errors = ArrayBuffer[LogEntry]() + + private val startTime = System.currentTimeMillis + private def elapsedTime: Long = System.currentTimeMillis - startTime +} + +private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) { + def isFatal: Boolean = false + def format: String + + override def toString: String = line match { + case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}" + case None => s"${format} ${msg}" + } + + protected def tag(name: String, color: String): String = + s"[${color}${name}${Console.RESET}]" +} + +private class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + override def isFatal: Boolean = true + def format: String = tag("error", Console.RED) +} + +private class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("warn", Console.YELLOW) +} + +private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("info", Console.MAGENTA) +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala new file mode 100644 index 00000000..c20bd130 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala @@ -0,0 +1,51 @@ +// See LICENSE for license details. + +// This file contains macros for adding source locators at the point of invocation. +// +// This is not part of coreMacros to disallow this macro from being implicitly invoked in Chisel +// frontend (and generating source locators in Chisel core), which is almost certainly a bug. +// +// Note: While these functions and definitions are not private (macros can't be +// private), these are NOT meant to be part of the public API (yet) and no +// forward compatibility guarantees are made. +// A future revision may stabilize the source locator API to allow library +// writers to append source locator information at the point of a library +// function invocation. + +package chisel.internal.sourceinfo + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +/** Abstract base class for generalized source information. + */ +sealed trait SourceInfo + +sealed trait NoSourceInfo extends SourceInfo + +/** For when source info can't be generated because of a technical limitation, like for Reg because + * Scala macros don't support named or default arguments. + */ +case object UnlocatableSourceInfo extends NoSourceInfo + +/** For when source info isn't generated because the function is deprecated and we're lazy. + */ +case object DeprecatedSourceInfo extends NoSourceInfo + +/** For FIRRTL lines from a Scala source line. + */ +case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo + +/** Provides a macro that returns the source information at the invocation point. + */ +object SourceInfoMacro { + def generate_source_info(c: Context): c.Tree = { + import c.universe._ + val p = c.enclosingPosition + q"_root_.chisel.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" + } +} + +object SourceInfo { + implicit def materialize: SourceInfo = macro SourceInfoMacro.generate_source_info +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala new file mode 100644 index 00000000..70e9938b --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -0,0 +1,190 @@ +// See LICENSE for license details. + +package chisel.internal.firrtl + +import chisel._ +import core._ +import chisel.internal._ +import chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo} + +case class PrimOp(val name: String) { + override def toString: String = name +} + +object PrimOp { + val AddOp = PrimOp("add") + val SubOp = PrimOp("sub") + val TailOp = PrimOp("tail") + val HeadOp = PrimOp("head") + val TimesOp = PrimOp("mul") + val DivideOp = PrimOp("div") + val RemOp = PrimOp("rem") + val ShiftLeftOp = PrimOp("shl") + val ShiftRightOp = PrimOp("shr") + val DynamicShiftLeftOp = PrimOp("dshl") + val DynamicShiftRightOp = PrimOp("dshr") + val BitAndOp = PrimOp("and") + val BitOrOp = PrimOp("or") + val BitXorOp = PrimOp("xor") + val BitNotOp = PrimOp("not") + val ConcatOp = PrimOp("cat") + val BitsExtractOp = PrimOp("bits") + val LessOp = PrimOp("lt") + val LessEqOp = PrimOp("leq") + val GreaterOp = PrimOp("gt") + val GreaterEqOp = PrimOp("geq") + val EqualOp = PrimOp("eq") + val PadOp = PrimOp("pad") + val NotEqualOp = PrimOp("neq") + val NegOp = PrimOp("neg") + val MultiplexOp = PrimOp("mux") + val XorReduceOp = PrimOp("xorr") + val ConvertOp = PrimOp("cvt") + val AsUIntOp = PrimOp("asUInt") + val AsSIntOp = PrimOp("asSInt") +} + +abstract class Arg { + def fullName(ctx: Component): String = name + def name: String +} + +case class Node(id: HasId) extends Arg { + override def fullName(ctx: Component): String = id.getRef.fullName(ctx) + def name: String = id.getRef.name +} + +abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { + private[chisel] def forcedWidth = widthArg.known + private[chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) + + protected def minWidth: Int + if (forcedWidth) { + require(widthArg.get >= minWidth, + s"The literal value ${num} was elaborated with a specificed width of ${widthArg.get} bits, but at least ${minWidth} bits are required.") + } +} + +case class ILit(n: BigInt) extends Arg { + def name: String = n.toString +} + +case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")" + def minWidth: Int = 1 max n.bitLength + + require(n >= 0, s"UInt literal ${n} is negative") +} + +case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = { + val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n + s"asSInt(${ULit(unsigned, width).name})" + } + def minWidth: Int = 1 + n.bitLength +} + +case class Ref(name: String) extends Arg +case class ModuleIO(mod: Module, name: String) extends Arg { + override def fullName(ctx: Component): String = + if (mod eq ctx.id) name else s"${mod.getRef.name}.$name" +} +case class Slot(imm: Node, name: String) extends Arg { + override def fullName(ctx: Component): String = + if (imm.fullName(ctx).isEmpty) name else s"${imm.fullName(ctx)}.${name}" +} +case class Index(imm: Arg, value: Arg) extends Arg { + def name: String = s"[$value]" + override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]" +} + +object Width { + def apply(x: Int): Width = KnownWidth(x) + def apply(): Width = UnknownWidth() +} + +sealed abstract class Width { + type W = Int + def max(that: Width): Width = this.op(that, _ max _) + def + (that: Width): Width = this.op(that, _ + _) + def + (that: Int): Width = this.op(this, (a, b) => a + that) + def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that)) + def dynamicShiftLeft(that: Width): Width = + this.op(that, (a, b) => a + (1 << b) - 1) + + def known: Boolean + def get: W + protected def op(that: Width, f: (W, W) => W): Width +} + +sealed case class UnknownWidth() extends Width { + def known: Boolean = false + def get: Int = None.get + def op(that: Width, f: (W, W) => W): Width = this + override def toString: String = "" +} + +sealed case class KnownWidth(value: Int) extends Width { + require(value >= 0) + def known: Boolean = true + def get: Int = value + def op(that: Width, f: (W, W) => W): Width = that match { + case KnownWidth(x) => KnownWidth(f(value, x)) + case _ => that + } + override def toString: String = s"<${value.toString}>" +} + +sealed abstract class MemPortDirection(name: String) { + override def toString: String = name +} +object MemPortDirection { + object READ extends MemPortDirection("read") + object WRITE extends MemPortDirection("write") + object RDWR extends MemPortDirection("rdwr") + object INFER extends MemPortDirection("infer") +} + +abstract class Command { + def sourceInfo: SourceInfo +} +abstract class Definition extends Command { + def id: HasId + def name: String = id.getRef.name +} +case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition +case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command +case class DefWire(sourceInfo: SourceInfo, id: Data) extends Definition +case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg) extends Definition +case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition +case class DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition +case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition +case class DefMemPort[T <: Data](sourceInfo: SourceInfo, id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition +case class DefInstance(sourceInfo: SourceInfo, id: Module, ports: Seq[Port]) extends Definition +case class WhenBegin(sourceInfo: SourceInfo, pred: Arg) extends Command +case class WhenEnd(sourceInfo: SourceInfo) extends Command +case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command +case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command +case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command +case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) extends Command +case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg +case class Port(id: Data, dir: Direction) +case class Printf(sourceInfo: SourceInfo, clk: Arg, formatIn: String, ids: Seq[Arg]) extends Command { + require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") + def format: String = { + def escaped(x: Char) = { + require(x.toInt >= 0) + if (x == '"' || x == '\\') { + s"\\${x}" + } else if (x == '\n') { + "\\n" + } else { + require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved + x + } + } + formatIn.map(escaped _).mkString + } +} + +case class Circuit(name: String, components: Seq[Component]) -- cgit v1.2.3 From 3026dd214f3db3308eaf8f876d0fc03f75c577d3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 20 Jun 2016 11:38:26 -0700 Subject: Rename "package", "import", and explicit references to "chisel3". --- .../src/main/scala/chisel3/internal/Builder.scala | 34 +++++++++++----------- .../src/main/scala/chisel3/internal/Error.scala | 8 ++--- .../main/scala/chisel3/internal/SourceInfo.scala | 4 +-- .../main/scala/chisel3/internal/firrtl/IR.scala | 12 ++++---- 4 files changed, 29 insertions(+), 29 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 01628105..0e0a88cc 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -1,15 +1,15 @@ // See LICENSE for license details. -package chisel.internal +package chisel3.internal import scala.util.DynamicVariable import scala.collection.mutable.{ArrayBuffer, HashMap} -import chisel._ +import chisel3._ import core._ import firrtl._ -private[chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) { +private[chisel3] class Namespace(parent: Option[Namespace], keywords: Set[String]) { private val names = collection.mutable.HashMap[String, Long]() for (keyword <- keywords) names(keyword) = 1 @@ -38,7 +38,7 @@ private[chisel] class Namespace(parent: Option[Namespace], keywords: Set[String] def child: Namespace = child(Set()) } -private[chisel] class IdGen { +private[chisel3] class IdGen { private var counter = -1L def next: Long = { counter += 1 @@ -46,12 +46,12 @@ private[chisel] class IdGen { } } -private[chisel] trait HasId { - private[chisel] def _onModuleClose {} // scalastyle:ignore method.name - private[chisel] val _parent = Builder.dynamicContext.currentModule +private[chisel3] trait HasId { + private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name + private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) - private[chisel] val _id = Builder.idGen.next + private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { case x: HasId => _id == x._id @@ -68,12 +68,12 @@ private[chisel] trait HasId { for(hook <- postname_hooks) { hook(name) } this } - private[chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook + private[chisel3] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook // Uses a namespace to convert suggestion into a true name // Will not do any naming if the reference already assigned. // (e.g. tried to suggest a name to part of a Bundle) - private[chisel] def forceName(default: =>String, namespace: Namespace): Unit = + private[chisel3] def forceName(default: =>String, namespace: Namespace): Unit = if(_ref.isEmpty) { val candidate_name = suggested_name.getOrElse(default) val available_name = namespace.name(candidate_name) @@ -81,14 +81,14 @@ private[chisel] trait HasId { } private var _ref: Option[Arg] = None - private[chisel] def setRef(imm: Arg): Unit = _ref = Some(imm) - private[chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) - private[chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) - private[chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) - private[chisel] def getRef: Arg = _ref.get + private[chisel3] def setRef(imm: Arg): Unit = _ref = Some(imm) + private[chisel3] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) + private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) + private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) + private[chisel3] def getRef: Arg = _ref.get } -private[chisel] class DynamicContext { +private[chisel3] class DynamicContext { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() @@ -96,7 +96,7 @@ private[chisel] class DynamicContext { val errors = new ErrorLog } -private[chisel] object Builder { +private[chisel3] object Builder { // All global mutable state must be referenced via dynamicContextVar!! private val dynamicContextVar = new DynamicVariable[Option[DynamicContext]](None) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala index f0481dc4..7ae0580f 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -1,20 +1,20 @@ // See LICENSE for license details. -package chisel.internal +package chisel3.internal import scala.collection.mutable.ArrayBuffer -import chisel.core._ +import chisel3.core._ class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) -private[chisel] object throwException { +private[chisel3] object throwException { def apply(s: String, t: Throwable = null): Nothing = throw new ChiselException(s, t) } /** Records and reports runtime errors and warnings. */ -private[chisel] class ErrorLog { +private[chisel3] class ErrorLog { def hasErrors: Boolean = errors.exists(_.isFatal) /** Log an error message */ diff --git a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala index c20bd130..5e3bf33e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala @@ -12,7 +12,7 @@ // writers to append source locator information at the point of a library // function invocation. -package chisel.internal.sourceinfo +package chisel3.internal.sourceinfo import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context @@ -42,7 +42,7 @@ object SourceInfoMacro { def generate_source_info(c: Context): c.Tree = { import c.universe._ val p = c.enclosingPosition - q"_root_.chisel.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" + q"_root_.chisel3.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 70e9938b..64d7d5fd 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -1,11 +1,11 @@ // See LICENSE for license details. -package chisel.internal.firrtl +package chisel3.internal.firrtl -import chisel._ +import chisel3._ import core._ -import chisel.internal._ -import chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo} +import chisel3.internal._ +import chisel3.internal.sourceinfo.{SourceInfo, NoSourceInfo} case class PrimOp(val name: String) { override def toString: String = name @@ -55,8 +55,8 @@ case class Node(id: HasId) extends Arg { } abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { - private[chisel] def forcedWidth = widthArg.known - private[chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) + private[chisel3] def forcedWidth = widthArg.known + private[chisel3] def width: Width = if (forcedWidth) widthArg else Width(minWidth) protected def minWidth: Int if (forcedWidth) { -- cgit v1.2.3 From c5f9ea3133ef363ff8944e17d94fea79767b6bed Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 6 Jul 2016 10:01:23 -0700 Subject: Rename "Chisel" to "chisel3" (only git mv). --- .../src/main/scala/chisel3/internal/Builder.scala | 123 ++++++++++++++ .../src/main/scala/chisel3/internal/Error.scala | 91 ++++++++++ .../main/scala/chisel3/internal/SourceInfo.scala | 51 ++++++ .../main/scala/chisel3/internal/firrtl/IR.scala | 188 +++++++++++++++++++++ 4 files changed, 453 insertions(+) create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/Builder.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/Error.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala new file mode 100644 index 00000000..d0e28b7c --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -0,0 +1,123 @@ +// See LICENSE for license details. + +package Chisel.internal + +import scala.util.DynamicVariable +import scala.collection.mutable.{ArrayBuffer, HashMap} + +import Chisel._ +import Chisel.internal.firrtl._ + +private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) { + private var i = 0L + private val names = collection.mutable.HashSet[String]() + + private def rename(n: String) = { i += 1; s"${n}_${i}" } + + def contains(elem: String): Boolean = { + keywords.contains(elem) || names.contains(elem) || + parent.map(_ contains elem).getOrElse(false) + } + + def name(elem: String): String = { + if (this contains elem) { + name(rename(elem)) + } else { + names += elem + elem + } + } + + def child(kws: Set[String]): Namespace = new Namespace(Some(this), kws) + def child: Namespace = child(Set()) +} + +private[Chisel] class IdGen { + private var counter = -1L + def next: Long = { + counter += 1 + counter + } +} + +private[Chisel] trait HasId { + private[Chisel] def _onModuleClose {} // scalastyle:ignore method.name + private[Chisel] val _parent = Builder.dynamicContext.currentModule + _parent.foreach(_.addId(this)) + + private[Chisel] val _id = Builder.idGen.next + override def hashCode: Int = _id.toInt + override def equals(that: Any): Boolean = that match { + case x: HasId => _id == x._id + case _ => false + } + + // Facilities for 'suggesting' a name to this. + // Post-name hooks called to carry the suggestion to other candidates as needed + private var suggested_name: Option[String] = None + private val postname_hooks = scala.collection.mutable.ListBuffer.empty[String=>Unit] + // Only takes the first suggestion! + def suggestName(name: =>String): this.type = { + if(suggested_name.isEmpty) suggested_name = Some(name) + for(hook <- postname_hooks) { hook(name) } + this + } + private[Chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook + + // Uses a namespace to convert suggestion into a true name + // Will not do any naming if the reference already assigned. + // (e.g. tried to suggest a name to part of a Bundle) + private[Chisel] def forceName(default: =>String, namespace: Namespace): Unit = + if(_ref.isEmpty) { + val candidate_name = suggested_name.getOrElse(default) + val available_name = namespace.name(candidate_name) + setRef(Ref(available_name)) + } + + private var _ref: Option[Arg] = None + private[Chisel] def setRef(imm: Arg): Unit = _ref = Some(imm) + private[Chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) + private[Chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) + private[Chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) + private[Chisel] def getRef: Arg = _ref.get +} + +private[Chisel] class DynamicContext { + val idGen = new IdGen + val globalNamespace = new Namespace(None, Set()) + val components = ArrayBuffer[Component]() + var currentModule: Option[Module] = None + val errors = new ErrorLog +} + +private[Chisel] object Builder { + // All global mutable state must be referenced via dynamicContextVar!! + private val dynamicContextVar = new DynamicVariable[Option[DynamicContext]](None) + + def dynamicContext: DynamicContext = + dynamicContextVar.value getOrElse (new DynamicContext) + def idGen: IdGen = dynamicContext.idGen + def globalNamespace: Namespace = dynamicContext.globalNamespace + def components: ArrayBuffer[Component] = dynamicContext.components + + def pushCommand[T <: Command](c: T): T = { + dynamicContext.currentModule.foreach(_._commands += c) + c + } + def pushOp[T <: Data](cmd: DefPrim[T]): T = pushCommand(cmd).id + + def errors: ErrorLog = dynamicContext.errors + def error(m: => String): Unit = errors.error(m) + + def build[T <: Module](f: => T): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext)) { + errors.info("Elaborating design...") + val mod = f + mod.forceName(mod.name, globalNamespace) + errors.checkpoint() + errors.info("Done elaborating.") + + Circuit(components.last.name, components) + } + } +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala new file mode 100644 index 00000000..6c4c0880 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -0,0 +1,91 @@ +// See LICENSE for license details. + +package Chisel.internal + +import scala.collection.mutable.ArrayBuffer + +import Chisel._ + +class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) + +private[Chisel] object throwException { + def apply(s: String, t: Throwable = null): Nothing = + throw new ChiselException(s, t) +} + +/** Records and reports runtime errors and warnings. */ +private[Chisel] class ErrorLog { + def hasErrors: Boolean = errors.exists(_.isFatal) + + /** Log an error message */ + def error(m: => String): Unit = + errors += new Error(m, getUserLineNumber) + + /** Log a warning message */ + def warning(m: => String): Unit = + errors += new Warning(m, getUserLineNumber) + + /** Emit an informational message */ + def info(m: String): Unit = + println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) // scalastyle:ignore regex + + /** Prints error messages generated by Chisel at runtime. */ + def report(): Unit = errors foreach println // scalastyle:ignore regex + + /** Throw an exception if any errors have yet occurred. */ + def checkpoint(): Unit = if(hasErrors) { + import Console._ + throwException(errors.map(_ + "\n").reduce(_ + _) + + UNDERLINED + "CODE HAS " + errors.filter(_.isFatal).length + RESET + + UNDERLINED + " " + RED + "ERRORS" + RESET + + UNDERLINED + " and " + errors.filterNot(_.isFatal).length + RESET + + UNDERLINED + " " + YELLOW + "WARNINGS" + RESET) + } + + private def findFirstUserFrame(stack: Array[StackTraceElement]): Option[StackTraceElement] = { + def isUserCode(ste: StackTraceElement): Boolean = { + def isUserModule(c: Class[_]): Boolean = + c != null && (c == classOf[Module] || isUserModule(c.getSuperclass)) + isUserModule(Class.forName(ste.getClassName)) + } + + stack.indexWhere(isUserCode) match { + case x if x < 0 => None + case x => Some(stack(x)) + } + } + + private def getUserLineNumber = + findFirstUserFrame(Thread.currentThread().getStackTrace) + + private val errors = ArrayBuffer[LogEntry]() + + private val startTime = System.currentTimeMillis + private def elapsedTime: Long = System.currentTimeMillis - startTime +} + +private abstract class LogEntry(msg: => String, line: Option[StackTraceElement]) { + def isFatal: Boolean = false + def format: String + + override def toString: String = line match { + case Some(l) => s"${format} ${l.getFileName}:${l.getLineNumber}: ${msg} in class ${l.getClassName}" + case None => s"${format} ${msg}" + } + + protected def tag(name: String, color: String): String = + s"[${color}${name}${Console.RESET}]" +} + +private class Error(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + override def isFatal: Boolean = true + def format: String = tag("error", Console.RED) +} + +private class Warning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("warn", Console.YELLOW) +} + +private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("info", Console.MAGENTA) +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala new file mode 100644 index 00000000..66bfc7a4 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala @@ -0,0 +1,51 @@ +// See LICENSE for license details. + +// This file contains macros for adding source locators at the point of invocation. +// +// This is not part of coreMacros to disallow this macro from being implicitly invoked in Chisel +// frontend (and generating source locators in Chisel core), which is almost certainly a bug. +// +// Note: While these functions and definitions are not private (macros can't be +// private), these are NOT meant to be part of the public API (yet) and no +// forward compatibility guarantees are made. +// A future revision may stabilize the source locator API to allow library +// writers to append source locator information at the point of a library +// function invocation. + +package Chisel.internal.sourceinfo + +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + +/** Abstract base class for generalized source information. + */ +sealed trait SourceInfo + +sealed trait NoSourceInfo extends SourceInfo + +/** For when source info can't be generated because of a technical limitation, like for Reg because + * Scala macros don't support named or default arguments. + */ +case object UnlocatableSourceInfo extends NoSourceInfo + +/** For when source info isn't generated because the function is deprecated and we're lazy. + */ +case object DeprecatedSourceInfo extends NoSourceInfo + +/** For FIRRTL lines from a Scala source line. + */ +case class SourceLine(filename: String, line: Int, col: Int) extends SourceInfo + +/** Provides a macro that returns the source information at the invocation point. + */ +object SourceInfoMacro { + def generate_source_info(c: Context): c.Tree = { + import c.universe._ + val p = c.enclosingPosition + q"_root_.Chisel.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" + } +} + +object SourceInfo { + implicit def materialize: SourceInfo = macro SourceInfoMacro.generate_source_info +} diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala new file mode 100644 index 00000000..62784cee --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -0,0 +1,188 @@ +// See LICENSE for license details. + +package Chisel.internal.firrtl +import Chisel._ +import Chisel.internal._ +import Chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo} + +case class PrimOp(val name: String) { + override def toString: String = name +} + +object PrimOp { + val AddOp = PrimOp("add") + val SubOp = PrimOp("sub") + val TailOp = PrimOp("tail") + val HeadOp = PrimOp("head") + val TimesOp = PrimOp("mul") + val DivideOp = PrimOp("div") + val RemOp = PrimOp("rem") + val ShiftLeftOp = PrimOp("shl") + val ShiftRightOp = PrimOp("shr") + val DynamicShiftLeftOp = PrimOp("dshl") + val DynamicShiftRightOp = PrimOp("dshr") + val BitAndOp = PrimOp("and") + val BitOrOp = PrimOp("or") + val BitXorOp = PrimOp("xor") + val BitNotOp = PrimOp("not") + val ConcatOp = PrimOp("cat") + val BitsExtractOp = PrimOp("bits") + val LessOp = PrimOp("lt") + val LessEqOp = PrimOp("leq") + val GreaterOp = PrimOp("gt") + val GreaterEqOp = PrimOp("geq") + val EqualOp = PrimOp("eq") + val PadOp = PrimOp("pad") + val NotEqualOp = PrimOp("neq") + val NegOp = PrimOp("neg") + val MultiplexOp = PrimOp("mux") + val XorReduceOp = PrimOp("xorr") + val ConvertOp = PrimOp("cvt") + val AsUIntOp = PrimOp("asUInt") + val AsSIntOp = PrimOp("asSInt") +} + +abstract class Arg { + def fullName(ctx: Component): String = name + def name: String +} + +case class Node(id: HasId) extends Arg { + override def fullName(ctx: Component): String = id.getRef.fullName(ctx) + def name: String = id.getRef.name +} + +abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { + private[Chisel] def forcedWidth = widthArg.known + private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) + + protected def minWidth: Int + if (forcedWidth) { + require(widthArg.get >= minWidth, + s"The literal value ${num} was elaborated with a specificed width of ${widthArg.get} bits, but at least ${minWidth} bits are required.") + } +} + +case class ILit(n: BigInt) extends Arg { + def name: String = n.toString +} + +case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = "UInt" + width + "(\"h0" + num.toString(16) + "\")" + def minWidth: Int = 1 max n.bitLength + + require(n >= 0, s"UInt literal ${n} is negative") +} + +case class SLit(n: BigInt, w: Width) extends LitArg(n, w) { + def name: String = { + val unsigned = if (n < 0) (BigInt(1) << width.get) + n else n + s"asSInt(${ULit(unsigned, width).name})" + } + def minWidth: Int = 1 + n.bitLength +} + +case class Ref(name: String) extends Arg +case class ModuleIO(mod: Module, name: String) extends Arg { + override def fullName(ctx: Component): String = + if (mod eq ctx.id) name else s"${mod.getRef.name}.$name" +} +case class Slot(imm: Node, name: String) extends Arg { + override def fullName(ctx: Component): String = + if (imm.fullName(ctx).isEmpty) name else s"${imm.fullName(ctx)}.${name}" +} +case class Index(imm: Arg, value: Arg) extends Arg { + def name: String = s"[$value]" + override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]" +} + +object Width { + def apply(x: Int): Width = KnownWidth(x) + def apply(): Width = UnknownWidth() +} + +sealed abstract class Width { + type W = Int + def max(that: Width): Width = this.op(that, _ max _) + def + (that: Width): Width = this.op(that, _ + _) + def + (that: Int): Width = this.op(this, (a, b) => a + that) + def shiftRight(that: Int): Width = this.op(this, (a, b) => 0 max (a - that)) + def dynamicShiftLeft(that: Width): Width = + this.op(that, (a, b) => a + (1 << b) - 1) + + def known: Boolean + def get: W + protected def op(that: Width, f: (W, W) => W): Width +} + +sealed case class UnknownWidth() extends Width { + def known: Boolean = false + def get: Int = None.get + def op(that: Width, f: (W, W) => W): Width = this + override def toString: String = "" +} + +sealed case class KnownWidth(value: Int) extends Width { + require(value >= 0) + def known: Boolean = true + def get: Int = value + def op(that: Width, f: (W, W) => W): Width = that match { + case KnownWidth(x) => KnownWidth(f(value, x)) + case _ => that + } + override def toString: String = s"<${value.toString}>" +} + +sealed abstract class MemPortDirection(name: String) { + override def toString: String = name +} +object MemPortDirection { + object READ extends MemPortDirection("read") + object WRITE extends MemPortDirection("write") + object RDWR extends MemPortDirection("rdwr") + object INFER extends MemPortDirection("infer") +} + +abstract class Command { + def sourceInfo: SourceInfo +} +abstract class Definition extends Command { + def id: HasId + def name: String = id.getRef.name +} +case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition +case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command +case class DefWire(sourceInfo: SourceInfo, id: Data) extends Definition +case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg) extends Definition +case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg) extends Definition +case class DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition +case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, size: Int) extends Definition +case class DefMemPort[T <: Data](sourceInfo: SourceInfo, id: T, source: Node, dir: MemPortDirection, index: Arg, clock: Arg) extends Definition +case class DefInstance(sourceInfo: SourceInfo, id: Module, ports: Seq[Port]) extends Definition +case class WhenBegin(sourceInfo: SourceInfo, pred: Arg) extends Command +case class WhenEnd(sourceInfo: SourceInfo) extends Command +case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command +case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command +case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command +case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) extends Command +case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg +case class Port(id: Data, dir: Direction) +case class Printf(sourceInfo: SourceInfo, clk: Arg, formatIn: String, ids: Seq[Arg]) extends Command { + require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") + def format: String = { + def escaped(x: Char) = { + require(x.toInt >= 0) + if (x == '"' || x == '\\') { + s"\\${x}" + } else if (x == '\n') { + "\\n" + } else { + require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved + x + } + } + formatIn.map(escaped _).mkString + } +} + +case class Circuit(name: String, components: Seq[Component]) -- cgit v1.2.3 From 12810b5efe6a8f872fbc1c63cdfb835ca354624f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 6 Jul 2016 09:31:47 -0700 Subject: Update Chisel -> chisel3 references. --- .../src/main/scala/chisel3/internal/Builder.scala | 54 ++++++++++++---------- .../src/main/scala/chisel3/internal/Error.scala | 8 ++-- .../main/scala/chisel3/internal/SourceInfo.scala | 4 +- .../main/scala/chisel3/internal/firrtl/IR.scala | 14 +++--- 4 files changed, 44 insertions(+), 36 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index d0e28b7c..0e0a88cc 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -1,29 +1,35 @@ // See LICENSE for license details. -package Chisel.internal +package chisel3.internal import scala.util.DynamicVariable import scala.collection.mutable.{ArrayBuffer, HashMap} -import Chisel._ -import Chisel.internal.firrtl._ +import chisel3._ +import core._ +import firrtl._ -private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String]) { - private var i = 0L - private val names = collection.mutable.HashSet[String]() +private[chisel3] class Namespace(parent: Option[Namespace], keywords: Set[String]) { + private val names = collection.mutable.HashMap[String, Long]() + for (keyword <- keywords) + names(keyword) = 1 - private def rename(n: String) = { i += 1; s"${n}_${i}" } + private def rename(n: String): String = { + val index = names.getOrElse(n, 1L) + val tryName = s"${n}_${index}" + names(n) = index + 1 + if (this contains tryName) rename(n) else tryName + } def contains(elem: String): Boolean = { - keywords.contains(elem) || names.contains(elem) || - parent.map(_ contains elem).getOrElse(false) + names.contains(elem) || parent.map(_ contains elem).getOrElse(false) } def name(elem: String): String = { if (this contains elem) { name(rename(elem)) } else { - names += elem + names(elem) = 1 elem } } @@ -32,7 +38,7 @@ private[Chisel] class Namespace(parent: Option[Namespace], keywords: Set[String] def child: Namespace = child(Set()) } -private[Chisel] class IdGen { +private[chisel3] class IdGen { private var counter = -1L def next: Long = { counter += 1 @@ -40,12 +46,12 @@ private[Chisel] class IdGen { } } -private[Chisel] trait HasId { - private[Chisel] def _onModuleClose {} // scalastyle:ignore method.name - private[Chisel] val _parent = Builder.dynamicContext.currentModule +private[chisel3] trait HasId { + private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name + private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) - private[Chisel] val _id = Builder.idGen.next + private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { case x: HasId => _id == x._id @@ -62,12 +68,12 @@ private[Chisel] trait HasId { for(hook <- postname_hooks) { hook(name) } this } - private[Chisel] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook + private[chisel3] def addPostnameHook(hook: String=>Unit): Unit = postname_hooks += hook // Uses a namespace to convert suggestion into a true name // Will not do any naming if the reference already assigned. // (e.g. tried to suggest a name to part of a Bundle) - private[Chisel] def forceName(default: =>String, namespace: Namespace): Unit = + private[chisel3] def forceName(default: =>String, namespace: Namespace): Unit = if(_ref.isEmpty) { val candidate_name = suggested_name.getOrElse(default) val available_name = namespace.name(candidate_name) @@ -75,14 +81,14 @@ private[Chisel] trait HasId { } private var _ref: Option[Arg] = None - private[Chisel] def setRef(imm: Arg): Unit = _ref = Some(imm) - private[Chisel] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) - private[Chisel] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) - private[Chisel] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) - private[Chisel] def getRef: Arg = _ref.get + private[chisel3] def setRef(imm: Arg): Unit = _ref = Some(imm) + private[chisel3] def setRef(parent: HasId, name: String): Unit = setRef(Slot(Node(parent), name)) + private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) + private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) + private[chisel3] def getRef: Arg = _ref.get } -private[Chisel] class DynamicContext { +private[chisel3] class DynamicContext { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() @@ -90,7 +96,7 @@ private[Chisel] class DynamicContext { val errors = new ErrorLog } -private[Chisel] object Builder { +private[chisel3] object Builder { // All global mutable state must be referenced via dynamicContextVar!! private val dynamicContextVar = new DynamicVariable[Option[DynamicContext]](None) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala index 6c4c0880..7ae0580f 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -1,20 +1,20 @@ // See LICENSE for license details. -package Chisel.internal +package chisel3.internal import scala.collection.mutable.ArrayBuffer -import Chisel._ +import chisel3.core._ class ChiselException(message: String, cause: Throwable) extends Exception(message, cause) -private[Chisel] object throwException { +private[chisel3] object throwException { def apply(s: String, t: Throwable = null): Nothing = throw new ChiselException(s, t) } /** Records and reports runtime errors and warnings. */ -private[Chisel] class ErrorLog { +private[chisel3] class ErrorLog { def hasErrors: Boolean = errors.exists(_.isFatal) /** Log an error message */ diff --git a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala index 66bfc7a4..5e3bf33e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/SourceInfo.scala @@ -12,7 +12,7 @@ // writers to append source locator information at the point of a library // function invocation. -package Chisel.internal.sourceinfo +package chisel3.internal.sourceinfo import scala.language.experimental.macros import scala.reflect.macros.blackbox.Context @@ -42,7 +42,7 @@ object SourceInfoMacro { def generate_source_info(c: Context): c.Tree = { import c.universe._ val p = c.enclosingPosition - q"_root_.Chisel.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" + q"_root_.chisel3.internal.sourceinfo.SourceLine(${p.source.file.name}, ${p.line}, ${p.column})" } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 62784cee..64d7d5fd 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -1,9 +1,11 @@ // See LICENSE for license details. -package Chisel.internal.firrtl -import Chisel._ -import Chisel.internal._ -import Chisel.internal.sourceinfo.{SourceInfo, NoSourceInfo} +package chisel3.internal.firrtl + +import chisel3._ +import core._ +import chisel3.internal._ +import chisel3.internal.sourceinfo.{SourceInfo, NoSourceInfo} case class PrimOp(val name: String) { override def toString: String = name @@ -53,8 +55,8 @@ case class Node(id: HasId) extends Arg { } abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { - private[Chisel] def forcedWidth = widthArg.known - private[Chisel] def width: Width = if (forcedWidth) widthArg else Width(minWidth) + private[chisel3] def forcedWidth = widthArg.known + private[chisel3] def width: Width = if (forcedWidth) widthArg else Width(minWidth) protected def minWidth: Int if (forcedWidth) { -- cgit v1.2.3 From 01e14c8c885527861152443f1233fa77b03cb8b5 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 19 Jul 2016 16:51:21 -0700 Subject: Merge in "complete" versions of Mem, Reg. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index e5b85736..168e19b2 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -124,7 +124,11 @@ private[chisel3] object Builder { forcedModule._commands += c c } - def pushOp[T <: Data](cmd: DefPrim[T]): T = pushCommand(cmd).id + def pushOp[T <: Data](cmd: DefPrim[T]): T = { + // Bind each element of the returned Data to being a Op + Binding.bind(cmd.id, OpBinder(forcedModule), "Error: During op creation, fresh result") + pushCommand(cmd).id + } def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) -- cgit v1.2.3 From c907eabfb65cd6442e35588b095ca031e2bdad7a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 7 Aug 2016 17:09:42 -0700 Subject: Legalize identifier names before printing It's not entirely clear what the FIRRTL implementation supports, so I'm using the ANSI C requirements for the time being. --- .../src/main/scala/chisel3/internal/Builder.scala | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 0e0a88cc..cecbd91e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -21,16 +21,25 @@ private[chisel3] class Namespace(parent: Option[Namespace], keywords: Set[String if (this contains tryName) rename(n) else tryName } + private def sanitize(s: String): String = { + // TODO what character set does FIRRTL truly support? using ANSI C for now + def legalStart(c: Char) = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' + def legal(c: Char) = legalStart(c) || (c >= '0' && c <= '9') + val res = s filter legal + if (res.isEmpty || !legalStart(res.head)) s"_$res" else res + } + def contains(elem: String): Boolean = { names.contains(elem) || parent.map(_ contains elem).getOrElse(false) } def name(elem: String): String = { - if (this contains elem) { - name(rename(elem)) + val sanitized = sanitize(elem) + if (this contains sanitized) { + name(rename(sanitized)) } else { - names(elem) = 1 - elem + names(sanitized) = 1 + sanitized } } -- cgit v1.2.3 From 8c8349e3eab69235f48826b59af8f67fe0b3e80c Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 12 Aug 2016 09:39:39 -0700 Subject: Add support for per-Module compilation options. Nothing uses these now, but when we integrate Stephen's PR200, we'll need a way to selectively enable some strict connection checks on a file by file basis. We plan to do this using package imports which will define suitable compilation options. --- .../src/main/scala/chisel3/internal/Builder.scala | 11 ++++++++--- .../src/main/scala/chisel3/internal/CompileOptions.scala | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index cecbd91e..68dd269c 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -97,12 +97,16 @@ private[chisel3] trait HasId { private[chisel3] def getRef: Arg = _ref.get } -private[chisel3] class DynamicContext { +private[chisel3] class DynamicContext(optionMap: Option[Map[String, String]] = None) { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() var currentModule: Option[Module] = None val errors = new ErrorLog + val compileOptions = new CompileOptions(optionMap match { + case Some(map: Map[String, String]) => map + case None => Map[String, String]() + }) } private[chisel3] object Builder { @@ -115,6 +119,7 @@ private[chisel3] object Builder { def globalNamespace: Namespace = dynamicContext.globalNamespace def components: ArrayBuffer[Component] = dynamicContext.components + def compileOptions = dynamicContext.compileOptions def pushCommand[T <: Command](c: T): T = { dynamicContext.currentModule.foreach(_._commands += c) c @@ -124,8 +129,8 @@ private[chisel3] object Builder { def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) - def build[T <: Module](f: => T): Circuit = { - dynamicContextVar.withValue(Some(new DynamicContext)) { + def build[T <: Module](f: => T, optionMap: Option[Map[String, String]] = None): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext(optionMap))) { errors.info("Elaborating design...") val mod = f mod.forceName(mod.name, globalNamespace) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala new file mode 100644 index 00000000..12789855 --- /dev/null +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -0,0 +1,16 @@ +// See LICENSE for license details. + +package chisel3.internal + +/** Initialize compilation options from a string map. + * + * @param optionsMap the map from "option" to "value" + */ +class CompileOptions(optionsMap: Map[String, String]) { + // The default for settings related to "strictness". + val strictDefault: String = optionsMap.getOrElse("strict", "false") + // Should Bundle connections require a strict match of fields. + // If true and the same fields aren't present in both source and sink, a MissingFieldException, + // MissingLeftFieldException, or MissingRightFieldException will be thrown. + val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean +} -- cgit v1.2.3 From 4ab2aa0e9209000fb0ba1299ac18db2e033f708f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 12 Aug 2016 14:17:52 -0700 Subject: Use compileOptions to determine if Missing...FieldExceptions are thrown. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index dddc261e..9f2b1631 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -118,6 +118,7 @@ private[chisel3] object Builder { def idGen: IdGen = dynamicContext.idGen def globalNamespace: Namespace = dynamicContext.globalNamespace def components: ArrayBuffer[Component] = dynamicContext.components + def compileOptions = dynamicContext.compileOptions def currentModule: Option[Module] = dynamicContext.currentModule def currentModule_=(target: Option[Module]): Unit = { @@ -133,7 +134,6 @@ private[chisel3] object Builder { // TODO(twigg): Ideally, binding checks and new bindings would all occur here // However, rest of frontend can't support this yet. - def compileOptions = dynamicContext.compileOptions def pushCommand[T <: Command](c: T): T = { forcedModule._commands += c c -- cgit v1.2.3 From e1e7c7ea3359df1351ba979287b62458e411e846 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 8 Aug 2016 16:54:05 -0700 Subject: Provide public SignalID trait to be used to conjure up a signal identifier. --- .../src/main/scala/chisel3/internal/Builder.scala | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index cecbd91e..dd4b3264 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -55,11 +55,30 @@ private[chisel3] class IdGen { } } -private[chisel3] trait HasId { +/** Public API to Nodes. + * currently, the node's name, the full path name, and a reference to its parent. + */ +trait SignalID { + def signalName(component: Component): String + def signalPathName(component: Component, separator: String = "_"): String + def signalParent: Module +} + +private[chisel3] trait HasId extends SignalID { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) + // Implementation of public methods. + override def signalParent = _parent.get + override def signalName(component: Component) = _ref.get.fullName(component) + override def signalPathName(component: Component, separator: String = "_"): String = { + _parent match { + case Some(p) => p.signalPathName(component, separator) + separator + signalName(component) + case None => signalName(component) + } + } + private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { -- cgit v1.2.3 From 0744b3e5f9c0648878b97d3375cd7d88e2d0ee08 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 10 Aug 2016 17:07:31 -0700 Subject: Add component to signature. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index dd4b3264..21f32483 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -55,13 +55,15 @@ private[chisel3] class IdGen { } } -/** Public API to Nodes. - * currently, the node's name, the full path name, and a reference to its parent. +/** Public API to access Node/Signal names. + * currently, the node's name, the full path name, and references to its parent Module and component. + * These are only valid once the design has been elaborated, and should not be used during its construction. */ trait SignalID { def signalName(component: Component): String - def signalPathName(component: Component, separator: String = "_"): String + def signalPathName(component: Component, separator: String = "."): String def signalParent: Module + def signalComponent: Option[Component] } private[chisel3] trait HasId extends SignalID { @@ -78,6 +80,7 @@ private[chisel3] trait HasId extends SignalID { case None => signalName(component) } } + override def signalComponent: Option[Component] = None private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt -- cgit v1.2.3 From f41f2533c55e506f7d5bf2ee0198de4d9a3dbea3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 16 Aug 2016 11:59:20 -0700 Subject: Reduce rocket-chip elaboration errors. --- chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index 12789855..b809b8fe 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -9,8 +9,14 @@ package chisel3.internal class CompileOptions(optionsMap: Map[String, String]) { // The default for settings related to "strictness". val strictDefault: String = optionsMap.getOrElse("strict", "false") + val looseDefault: String = (!(strictDefault.toBoolean)).toString // Should Bundle connections require a strict match of fields. // If true and the same fields aren't present in both source and sink, a MissingFieldException, // MissingLeftFieldException, or MissingRightFieldException will be thrown. val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean + val regTypeMustBeUnbound: Boolean = optionsMap.getOrElse("regTypeMustBeUnbound", strictDefault).toBoolean + val autoIOWrap: Boolean = optionsMap.getOrElse("autoIOWrap", looseDefault).toBoolean + val portDeterminesDirection: Boolean = optionsMap.getOrElse("portDeterminesDirection", looseDefault).toBoolean + val internalConnectionToInputOk: Boolean = optionsMap.getOrElse("internalConnectionToInputOk", looseDefault).toBoolean + val tryConnectionsSwapped: Boolean = optionsMap.getOrElse("tryConnectionsSwapped", looseDefault).toBoolean } -- cgit v1.2.3 From 7922f8d4998dd902ee18a6e85e4a404a1f29eb3f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 17 Aug 2016 13:30:05 -0700 Subject: Rocket-chip updates. Assume LHSItOutput if neither side is driving. Restore Wire()'s removal of direction in binding. --- chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala | 1 + 1 file changed, 1 insertion(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index b809b8fe..93879950 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -19,4 +19,5 @@ class CompileOptions(optionsMap: Map[String, String]) { val portDeterminesDirection: Boolean = optionsMap.getOrElse("portDeterminesDirection", looseDefault).toBoolean val internalConnectionToInputOk: Boolean = optionsMap.getOrElse("internalConnectionToInputOk", looseDefault).toBoolean val tryConnectionsSwapped: Boolean = optionsMap.getOrElse("tryConnectionsSwapped", looseDefault).toBoolean + val assumeLHSIsOutput: Boolean = optionsMap.getOrElse("assumeLHSIsOutput", looseDefault).toBoolean } -- cgit v1.2.3 From 471a9e2d15d4c968fc6eca9a86c232c6c9c9322d Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 18 Aug 2016 15:26:39 -0700 Subject: Add assumeNoDirectionIsOutput. --- chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala | 1 + 1 file changed, 1 insertion(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index e040201b..912184fb 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -19,4 +19,5 @@ class CompileOptions(optionsMap: Map[String, String]) { val portDeterminesDirection: Boolean = optionsMap.getOrElse("portDeterminesDirection", looseDefault).toBoolean val tryConnectionsSwapped: Boolean = optionsMap.getOrElse("tryConnectionsSwapped", looseDefault).toBoolean val assumeLHSIsOutput: Boolean = optionsMap.getOrElse("assumeLHSIsOutput", looseDefault).toBoolean + val assumeNoDirectionIsOutput: Boolean = optionsMap.getOrElse("assumeNoDirectionIsOutput", looseDefault).toBoolean } -- cgit v1.2.3 From 2d01fdf6f26f480cb7ed19c1365f181ea717ddc2 Mon Sep 17 00:00:00 2001 From: Donggyu Kim Date: Mon, 15 Aug 2016 18:03:12 -0700 Subject: provides signal name methods for firrtl annotation and chisel testers * signalName: returns the chirrtl name of the signal * pathName: returns the full path name of the signal from the top module * parentPathName: returns the full path of the signal's parent module instance from the top module * parentModName: returns the signal's parent **module(not instance)** name. --- .../src/main/scala/chisel3/internal/Builder.scala | 44 +++++++++++++--------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 21f32483..bf78c410 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -59,29 +59,18 @@ private[chisel3] class IdGen { * currently, the node's name, the full path name, and references to its parent Module and component. * These are only valid once the design has been elaborated, and should not be used during its construction. */ -trait SignalID { - def signalName(component: Component): String - def signalPathName(component: Component, separator: String = "."): String - def signalParent: Module - def signalComponent: Option[Component] +trait SignalId { + def signalName: String + def pathName: String + def parentPathName: String + def parentModName: String } -private[chisel3] trait HasId extends SignalID { +private[chisel3] trait HasId extends SignalId { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) - // Implementation of public methods. - override def signalParent = _parent.get - override def signalName(component: Component) = _ref.get.fullName(component) - override def signalPathName(component: Component, separator: String = "_"): String = { - _parent match { - case Some(p) => p.signalPathName(component, separator) + separator + signalName(component) - case None => signalName(component) - } - } - override def signalComponent: Option[Component] = None - private[chisel3] val _id = Builder.idGen.next override def hashCode: Int = _id.toInt override def equals(that: Any): Boolean = that match { @@ -117,6 +106,27 @@ private[chisel3] trait HasId extends SignalID { private[chisel3] def setRef(parent: HasId, index: Int): Unit = setRef(Index(Node(parent), ILit(index))) private[chisel3] def setRef(parent: HasId, index: UInt): Unit = setRef(Index(Node(parent), index.ref)) private[chisel3] def getRef: Arg = _ref.get + + // Implementation of public methods. + def signalName = _parent match { + case Some(p) => p._component match { + case Some(c) => getRef fullName c + case None => throwException("signalName/pathName should be called after circuit elaboration") + } + case None => throwException("this cannot happen") + } + def pathName = _parent match { + case None => signalName + case Some(p) => s"${p.pathName}.$signalName" + } + def parentPathName = _parent match { + case Some(p) => p.pathName + case None => throwException(s"$signalName doesn't have a parent") + } + def parentModName = _parent match { + case Some(p) => p.modName + case None => throwException(s"$signalName doesn't have a parent") + } } private[chisel3] class DynamicContext { -- cgit v1.2.3 From 716de18b37c301523f8c6fb4954745aaa2a79bdb Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 23 Aug 2016 09:42:10 -0700 Subject: Swap name of compileOption "assumeNoDirectionIsOutput" to "assumeNoDirectionIsInput". --- chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index 912184fb..a0a20020 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -19,5 +19,5 @@ class CompileOptions(optionsMap: Map[String, String]) { val portDeterminesDirection: Boolean = optionsMap.getOrElse("portDeterminesDirection", looseDefault).toBoolean val tryConnectionsSwapped: Boolean = optionsMap.getOrElse("tryConnectionsSwapped", looseDefault).toBoolean val assumeLHSIsOutput: Boolean = optionsMap.getOrElse("assumeLHSIsOutput", looseDefault).toBoolean - val assumeNoDirectionIsOutput: Boolean = optionsMap.getOrElse("assumeNoDirectionIsOutput", looseDefault).toBoolean + val assumeNoDirectionIsInput: Boolean = optionsMap.getOrElse("assumeNoDirectionIsInput", looseDefault).toBoolean } -- cgit v1.2.3 From f5e9a6c6e55ba19a7c1f2353d0207189062db1c9 Mon Sep 17 00:00:00 2001 From: chick Date: Wed, 24 Aug 2016 17:09:41 -0700 Subject: Per Chisel meeting. signalName -> instanceName SignalId -> InstanceId Based on Stephen's comments on PR --- .../src/main/scala/chisel3/internal/Builder.scala | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index bf78c410..2dec78bb 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -59,14 +59,14 @@ private[chisel3] class IdGen { * currently, the node's name, the full path name, and references to its parent Module and component. * These are only valid once the design has been elaborated, and should not be used during its construction. */ -trait SignalId { - def signalName: String +trait InstanceId { + def instanceName: String def pathName: String def parentPathName: String def parentModName: String } -private[chisel3] trait HasId extends SignalId { +private[chisel3] trait HasId extends InstanceId { private[chisel3] def _onModuleClose {} // scalastyle:ignore method.name private[chisel3] val _parent = Builder.dynamicContext.currentModule _parent.foreach(_.addId(this)) @@ -108,7 +108,7 @@ private[chisel3] trait HasId extends SignalId { private[chisel3] def getRef: Arg = _ref.get // Implementation of public methods. - def signalName = _parent match { + def instanceName = _parent match { case Some(p) => p._component match { case Some(c) => getRef fullName c case None => throwException("signalName/pathName should be called after circuit elaboration") @@ -116,16 +116,16 @@ private[chisel3] trait HasId extends SignalId { case None => throwException("this cannot happen") } def pathName = _parent match { - case None => signalName - case Some(p) => s"${p.pathName}.$signalName" + case None => instanceName + case Some(p) => s"${p.pathName}.$instanceName" } def parentPathName = _parent match { case Some(p) => p.pathName - case None => throwException(s"$signalName doesn't have a parent") + case None => throwException(s"$instanceName doesn't have a parent") } def parentModName = _parent match { case Some(p) => p.modName - case None => throwException(s"$signalName doesn't have a parent") + case None => throwException(s"$instanceName doesn't have a parent") } } -- cgit v1.2.3 From 5fcdd12fe92bd22f9cdfb8f5e39e510684b709bf Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 29 Aug 2016 09:33:51 -0700 Subject: Rename individual compile options. Stricter values are "true". Current default (not strict) values are "false". --- .../src/main/scala/chisel3/internal/CompileOptions.scala | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index a0a20020..31d441c1 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -15,9 +15,8 @@ class CompileOptions(optionsMap: Map[String, String]) { // MissingLeftFieldException, or MissingRightFieldException will be thrown. val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean val regTypeMustBeUnbound: Boolean = optionsMap.getOrElse("regTypeMustBeUnbound", strictDefault).toBoolean - val autoIOWrap: Boolean = optionsMap.getOrElse("autoIOWrap", looseDefault).toBoolean - val portDeterminesDirection: Boolean = optionsMap.getOrElse("portDeterminesDirection", looseDefault).toBoolean - val tryConnectionsSwapped: Boolean = optionsMap.getOrElse("tryConnectionsSwapped", looseDefault).toBoolean - val assumeLHSIsOutput: Boolean = optionsMap.getOrElse("assumeLHSIsOutput", looseDefault).toBoolean - val assumeNoDirectionIsInput: Boolean = optionsMap.getOrElse("assumeNoDirectionIsInput", looseDefault).toBoolean + val declaredTypeMustBeUnbound: Boolean = optionsMap.getOrElse("declaredTypeMustBeUnbound", strictDefault).toBoolean + val requireIOWrap: Boolean = optionsMap.getOrElse("requireIOWrap", strictDefault).toBoolean + val dontTryConnectionsSwapped: Boolean = optionsMap.getOrElse("dontTryConnectionsSwapped", strictDefault).toBoolean + val dontAssumeDirectionality: Boolean = optionsMap.getOrElse("dontAssumeDirectionality", strictDefault).toBoolean } -- cgit v1.2.3 From 6df3a785f8abe706838bc5b4b35c3374b6512f96 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 29 Aug 2016 12:17:48 -0700 Subject: Pass compileOptions as an implicit Module parameter. --- .../src/main/scala/chisel3/internal/Builder.scala | 14 ++++---- .../scala/chisel3/internal/CompileOptions.scala | 39 ++++++++++++++-------- 2 files changed, 32 insertions(+), 21 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 9f2b1631..9b656dea 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -97,16 +97,16 @@ private[chisel3] trait HasId { private[chisel3] def getRef: Arg = _ref.get } -private[chisel3] class DynamicContext(optionMap: Option[Map[String, String]] = None) { +private[chisel3] class DynamicContext(moduleCompileOptions: Option[ExplicitCompileOptions] = None) { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() var currentModule: Option[Module] = None val errors = new ErrorLog - val compileOptions = new CompileOptions(optionMap match { - case Some(map: Map[String, String]) => map - case None => Map[String, String]() - }) + val compileOptions = moduleCompileOptions match { + case Some(options: ExplicitCompileOptions) => options + case None => chisel3.NotStrict.NotStrictCompileOptions + } } private[chisel3] object Builder { @@ -147,8 +147,8 @@ private[chisel3] object Builder { def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) - def build[T <: Module](f: => T, optionMap: Option[Map[String, String]] = None): Circuit = { - dynamicContextVar.withValue(Some(new DynamicContext(optionMap))) { + def build[T <: Module](f: => T, moduleCompileOptions: Option[ExplicitCompileOptions] = None): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext(moduleCompileOptions))) { errors.info("Elaborating design...") val mod = f mod.forceName(mod.name, globalNamespace) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index 31d441c1..2890f6dc 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -2,21 +2,32 @@ package chisel3.internal -/** Initialize compilation options from a string map. - * - * @param optionsMap the map from "option" to "value" - */ -class CompileOptions(optionsMap: Map[String, String]) { - // The default for settings related to "strictness". - val strictDefault: String = optionsMap.getOrElse("strict", "false") - val looseDefault: String = (!(strictDefault.toBoolean)).toString +trait CompileOptions { // Should Bundle connections require a strict match of fields. // If true and the same fields aren't present in both source and sink, a MissingFieldException, // MissingLeftFieldException, or MissingRightFieldException will be thrown. - val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean - val regTypeMustBeUnbound: Boolean = optionsMap.getOrElse("regTypeMustBeUnbound", strictDefault).toBoolean - val declaredTypeMustBeUnbound: Boolean = optionsMap.getOrElse("declaredTypeMustBeUnbound", strictDefault).toBoolean - val requireIOWrap: Boolean = optionsMap.getOrElse("requireIOWrap", strictDefault).toBoolean - val dontTryConnectionsSwapped: Boolean = optionsMap.getOrElse("dontTryConnectionsSwapped", strictDefault).toBoolean - val dontAssumeDirectionality: Boolean = optionsMap.getOrElse("dontAssumeDirectionality", strictDefault).toBoolean + val connectFieldsMustMatch: Boolean + val declaredTypeMustBeUnbound: Boolean + val requireIOWrap: Boolean + val dontTryConnectionsSwapped: Boolean + val dontAssumeDirectionality: Boolean } + +trait ExplicitCompileOptions extends CompileOptions + +///** Initialize compilation options from a string map. +// * +// * @param optionsMap the map from "option" to "value" +// */ +//class CompileOptions(optionsMap: Map[String, String]) { +// // The default for settings related to "strictness". +// val strictDefault: String = optionsMap.getOrElse("strict", "false") +// // Should Bundle connections require a strict match of fields. +// // If true and the same fields aren't present in both source and sink, a MissingFieldException, +// // MissingLeftFieldException, or MissingRightFieldException will be thrown. +// val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean +// val declaredTypeMustBeUnbound: Boolean = optionsMap.getOrElse("declaredTypeMustBeUnbound", strictDefault).toBoolean +// val requireIOWrap: Boolean = optionsMap.getOrElse("requireIOWrap", strictDefault).toBoolean +// val dontTryConnectionsSwapped: Boolean = optionsMap.getOrElse("dontTryConnectionsSwapped", strictDefault).toBoolean +// val dontAssumeDirectionality: Boolean = optionsMap.getOrElse("dontAssumeDirectionality", strictDefault).toBoolean +//} -- cgit v1.2.3 From 62817134d222747f1eab34626fe7b1bb13b9f6df Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 29 Aug 2016 13:45:05 -0700 Subject: Rename CompileOptions implicit objects. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 9b656dea..3191e384 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -105,7 +105,7 @@ private[chisel3] class DynamicContext(moduleCompileOptions: Option[ExplicitCompi val errors = new ErrorLog val compileOptions = moduleCompileOptions match { case Some(options: ExplicitCompileOptions) => options - case None => chisel3.NotStrict.NotStrictCompileOptions + case None => chisel3.NotStrict.CompileOptions } } -- cgit v1.2.3 From 4b88a5dd45337fa88178fe17324eef3661daf1b3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 1 Sep 2016 10:21:57 -0700 Subject: Move connection implicits from Module constructor to connection methods. Eliminate builder compileOptions. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 0376e067..8d376810 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -129,16 +129,12 @@ private[chisel3] trait HasId extends InstanceId { } } -private[chisel3] class DynamicContext(moduleCompileOptions: Option[ExplicitCompileOptions] = None) { +private[chisel3] class DynamicContext() { val idGen = new IdGen val globalNamespace = new Namespace(None, Set()) val components = ArrayBuffer[Component]() var currentModule: Option[Module] = None val errors = new ErrorLog - val compileOptions = moduleCompileOptions match { - case Some(options: ExplicitCompileOptions) => options - case None => chisel3.NotStrict.CompileOptions - } } private[chisel3] object Builder { @@ -150,7 +146,6 @@ private[chisel3] object Builder { def idGen: IdGen = dynamicContext.idGen def globalNamespace: Namespace = dynamicContext.globalNamespace def components: ArrayBuffer[Component] = dynamicContext.components - def compileOptions = dynamicContext.compileOptions def currentModule: Option[Module] = dynamicContext.currentModule def currentModule_=(target: Option[Module]): Unit = { @@ -179,8 +174,8 @@ private[chisel3] object Builder { def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) - def build[T <: Module](f: => T, moduleCompileOptions: Option[ExplicitCompileOptions] = None): Circuit = { - dynamicContextVar.withValue(Some(new DynamicContext(moduleCompileOptions))) { + def build[T <: Module](f: => T): Circuit = { + dynamicContextVar.withValue(Some(new DynamicContext())) { errors.info("Elaborating design...") val mod = f mod.forceName(mod.name, globalNamespace) -- cgit v1.2.3 From 0ed5eb48cdb916b644aaf9e5dbf48f6cfb6c60f4 Mon Sep 17 00:00:00 2001 From: Jack Koenig Date: Wed, 7 Sep 2016 14:18:29 -0700 Subject: Add Printable (#270) Printable is a new type that changes how printing of Chisel types is represented It uses an ordered collection rather than a format string and specifiers Features: - Custom String Interpolator for Scala-like printf - String-like manipulation of "hardware strings" for custom pretty-printing - Default pretty-printing for Chisel data types--- .../src/main/scala/chisel3/internal/firrtl/IR.scala | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 64d7d5fd..1f05b6e2 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -169,22 +169,6 @@ case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Comm case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) extends Command case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg case class Port(id: Data, dir: Direction) -case class Printf(sourceInfo: SourceInfo, clk: Arg, formatIn: String, ids: Seq[Arg]) extends Command { - require(formatIn.forall(c => c.toInt > 0 && c.toInt < 128), "format strings must comprise non-null ASCII values") - def format: String = { - def escaped(x: Char) = { - require(x.toInt >= 0) - if (x == '"' || x == '\\') { - s"\\${x}" - } else if (x == '\n') { - "\\n" - } else { - require(x.toInt >= 32) // TODO \xNN once FIRRTL issue #59 is resolved - x - } - } - formatIn.map(escaped _).mkString - } -} +case class Printf(sourceInfo: SourceInfo, clk: Arg, pable: Printable) extends Command case class Circuit(name: String, components: Seq[Component]) -- cgit v1.2.3 From a2cb95bfe9e9c30b73284e97048fa0187ab0ee1d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 21 Sep 2016 12:44:36 -0700 Subject: Make implicit clock name consistent (#288) In the Chisel frontend, the implicit clock is named clock, but in the generated FIRRTL, it is named clk. There is no reason for this discrepancy, and yet fixing it is painful, as it will break test harnesses. Better to take the pain now than later. Resolves #258.--- chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 1f05b6e2..e39b007e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -166,9 +166,9 @@ case class WhenEnd(sourceInfo: SourceInfo) extends Command case class Connect(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command case class BulkConnect(sourceInfo: SourceInfo, loc1: Node, loc2: Node) extends Command case class ConnectInit(sourceInfo: SourceInfo, loc: Node, exp: Arg) extends Command -case class Stop(sourceInfo: SourceInfo, clk: Arg, ret: Int) extends Command +case class Stop(sourceInfo: SourceInfo, clock: Arg, ret: Int) extends Command case class Component(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Arg case class Port(id: Data, dir: Direction) -case class Printf(sourceInfo: SourceInfo, clk: Arg, pable: Printable) extends Command +case class Printf(sourceInfo: SourceInfo, clock: Arg, pable: Printable) extends Command case class Circuit(name: String, components: Seq[Component]) -- cgit v1.2.3 From b18e98ba2d058c7dd24f96f005486b70c856aeca Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 21 Sep 2016 16:16:25 -0700 Subject: Expose FIRRTL asClock construct Additionally, fix Clock.asUInt (previously, it threw an esoteric exception), and add a simple test of both.--- chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala | 1 + 1 file changed, 1 insertion(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index e39b007e..0641686c 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -42,6 +42,7 @@ object PrimOp { val ConvertOp = PrimOp("cvt") val AsUIntOp = PrimOp("asUInt") val AsSIntOp = PrimOp("asSInt") + val AsClockOp = PrimOp("asClock") } abstract class Arg { -- cgit v1.2.3 From bd9276f4f78c712e98b658ad9e0df81abf94c57b Mon Sep 17 00:00:00 2001 From: ducky Date: Mon, 26 Sep 2016 14:12:05 -0700 Subject: Add Strict default for compile options --- .../src/main/scala/chisel3/internal/CompileOptions.scala | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala index 2890f6dc..2b913908 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala @@ -2,6 +2,9 @@ package chisel3.internal +import scala.language.experimental.macros +import scala.reflect.macros.blackbox.Context + trait CompileOptions { // Should Bundle connections require a strict match of fields. // If true and the same fields aren't present in both source and sink, a MissingFieldException, @@ -15,6 +18,11 @@ trait CompileOptions { trait ExplicitCompileOptions extends CompileOptions +object ExplicitCompileOptions { + // Provides a low priority Strict default. Can be overridden by importing the NotStrict option. + implicit def materialize: ExplicitCompileOptions = chisel3.Strict.CompileOptions +} + ///** Initialize compilation options from a string map. // * // * @param optionsMap the map from "option" to "value" -- cgit v1.2.3 From eb5e5dc30019be342b7a0534b425bf33b7984ce3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 29 Sep 2016 11:44:09 -0700 Subject: Massive rename of CompileOptions. Massage CompileOption names in an attempt to preserve default (Strict) CompileOptions in the absence of explicit imports. NOTE: Since the default is now strict, we may encounter errors when we generate connections for clients (i.e., in Vec.do_apply() when we wire up a sequence). We should really thread the CompileOptions through the macro system so the client's implicits are used. --- .../scala/chisel3/internal/CompileOptions.scala | 41 ---------------------- 1 file changed, 41 deletions(-) delete mode 100644 chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala b/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala deleted file mode 100644 index 2b913908..00000000 --- a/chiselFrontend/src/main/scala/chisel3/internal/CompileOptions.scala +++ /dev/null @@ -1,41 +0,0 @@ -// See LICENSE for license details. - -package chisel3.internal - -import scala.language.experimental.macros -import scala.reflect.macros.blackbox.Context - -trait CompileOptions { - // Should Bundle connections require a strict match of fields. - // If true and the same fields aren't present in both source and sink, a MissingFieldException, - // MissingLeftFieldException, or MissingRightFieldException will be thrown. - val connectFieldsMustMatch: Boolean - val declaredTypeMustBeUnbound: Boolean - val requireIOWrap: Boolean - val dontTryConnectionsSwapped: Boolean - val dontAssumeDirectionality: Boolean -} - -trait ExplicitCompileOptions extends CompileOptions - -object ExplicitCompileOptions { - // Provides a low priority Strict default. Can be overridden by importing the NotStrict option. - implicit def materialize: ExplicitCompileOptions = chisel3.Strict.CompileOptions -} - -///** Initialize compilation options from a string map. -// * -// * @param optionsMap the map from "option" to "value" -// */ -//class CompileOptions(optionsMap: Map[String, String]) { -// // The default for settings related to "strictness". -// val strictDefault: String = optionsMap.getOrElse("strict", "false") -// // Should Bundle connections require a strict match of fields. -// // If true and the same fields aren't present in both source and sink, a MissingFieldException, -// // MissingLeftFieldException, or MissingRightFieldException will be thrown. -// val connectFieldsMustMatch: Boolean = optionsMap.getOrElse("connectFieldsMustMatch", strictDefault).toBoolean -// val declaredTypeMustBeUnbound: Boolean = optionsMap.getOrElse("declaredTypeMustBeUnbound", strictDefault).toBoolean -// val requireIOWrap: Boolean = optionsMap.getOrElse("requireIOWrap", strictDefault).toBoolean -// val dontTryConnectionsSwapped: Boolean = optionsMap.getOrElse("dontTryConnectionsSwapped", strictDefault).toBoolean -// val dontAssumeDirectionality: Boolean = optionsMap.getOrElse("dontAssumeDirectionality", strictDefault).toBoolean -//} -- cgit v1.2.3 From b2373ebda5e63fa850de21585307013f8419320a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 5 Oct 2016 15:18:25 -0700 Subject: Make asInput/asOutput/flip deprecation warnings dynamic Code that imports Chisel._ shouldn't see them. Not sure if requireIOWrap is the right condition... or if cyan is a good choice of color for deprecation warnings. --- chiselFrontend/src/main/scala/chisel3/internal/Builder.scala | 2 ++ chiselFrontend/src/main/scala/chisel3/internal/Error.scala | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'chiselFrontend/src/main/scala/chisel3/internal') diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 8d376810..12cc840e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -173,6 +173,8 @@ private[chisel3] object Builder { def errors: ErrorLog = dynamicContext.errors def error(m: => String): Unit = errors.error(m) + def warning(m: => String): Unit = errors.warning(m) + def deprecated(m: => String): Unit = errors.deprecated(m) def build[T <: Module](f: => T): Circuit = { dynamicContextVar.withValue(Some(new DynamicContext())) { diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala index 7ae0580f..c5c67da4 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Error.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Error.scala @@ -25,6 +25,10 @@ private[chisel3] class ErrorLog { def warning(m: => String): Unit = errors += new Warning(m, getUserLineNumber) + /** Log a deprecation warning message */ + def deprecated(m: => String): Unit = + errors += new DeprecationWarning(m, getUserLineNumber) + /** Emit an informational message */ def info(m: String): Unit = println(new Info("[%2.3f] %s".format(elapsedTime/1e3, m), None)) // scalastyle:ignore regex @@ -86,6 +90,10 @@ private class Warning(msg: => String, line: Option[StackTraceElement]) extends L def format: String = tag("warn", Console.YELLOW) } +private class DeprecationWarning(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { + def format: String = tag("warn", Console.CYAN) +} + private class Info(msg: => String, line: Option[StackTraceElement]) extends LogEntry(msg, line) { def format: String = tag("info", Console.MAGENTA) } -- cgit v1.2.3