From 5999b489dd60aa022f26d254db9399ee13e7c3de Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Sat, 29 Apr 2017 21:44:30 -0400 Subject: [PATCH 01/35] VecLabel support --- .../src/main/scala/chisel3/core/Label.scala | 5 +++++ .../src/main/scala/chisel3/core/Mem.scala | 18 ++++++++++-------- .../scala/chisel3/internal/firrtl/IR.scala | 4 ++-- .../sourceinfo/SourceInfoTransform.scala | 4 ++-- .../chisel3/internal/firrtl/Emitter.scala | 4 ++-- src/main/scala/chisel3/package.scala | 1 + 6 files changed, 22 insertions(+), 14 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index 981114b..c846271 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -58,6 +58,11 @@ case class HLevel(id: HasId) extends LabelComp { def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" } +case class VLabel(id: HasId) extends LabelComp { + def name = s"[[${id.getRef.name}]]V" + def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]V" +} + object C { def apply(l: Label): LabelComp = l match { case Label(conf, _) => conf diff --git a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala index 1863e92..a278c3c 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Mem.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Mem.scala @@ -13,21 +13,22 @@ import chisel3.core.ExplicitCompileOptions.NotStrict object Mem { @deprecated("Mem argument order should be size, t; this will be removed by the official release", "chisel3") - def apply[T <: Data](t: T, size: Int): Mem[T] = do_apply(size, t)(UnlocatableSourceInfo) + def apply[T <: Data](t: T, size: Int, lbl: Label): Mem[T] = do_apply(size, t, lbl)(UnlocatableSourceInfo) /** Creates a combinational-read, sequential-write [[Mem]]. * * @param size number of elements in the memory * @param t data type of memory element */ - def apply[T <: Data](size: Int, t: T): Mem[T] = macro MemTransform.apply[T] - def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo): Mem[T] = { + def apply[T <: Data](size: Int, t: T): Mem[T] = do_apply(size, t, UnknownLabel)(UnlocatableSourceInfo) + def apply[T <: Data](size: Int, t: T, lbl: Label): Mem[T] = macro MemTransform.apply[T] + def do_apply[T <: Data](size: Int, t: T, lbl: Label)(implicit sourceInfo: SourceInfo): Mem[T] = { val mt = t.chiselCloneType Binding.bind(mt, NoDirectionBinder, "Error: fresh t") // TODO(twigg): Remove need for this Binding val mem = new Mem(mt, size) - pushCommand(DefMemory(sourceInfo, mem, mt, size)) // TODO multi-clock + pushCommand(DefMemory(sourceInfo, mem, mt, lbl, size)) // TODO multi-clock mem } } @@ -113,22 +114,23 @@ sealed class Mem[T <: Data](t: T, length: Int) extends MemBase(t, length) object SeqMem { @deprecated("SeqMem argument order should be size, t; this will be removed by the official release", "chisel3") - def apply[T <: Data](t: T, size: Int): SeqMem[T] = do_apply(size, t)(DeprecatedSourceInfo) + def apply[T <: Data](t: T, size: Int, lbl: Label): SeqMem[T] = do_apply(size, t, lbl)(DeprecatedSourceInfo) /** Creates a sequential-read, sequential-write [[SeqMem]]. * * @param size number of elements in the memory * @param t data type of memory element */ - def apply[T <: Data](size: Int, t: T): SeqMem[T] = macro MemTransform.apply[T] + def apply[T <: Data](size: Int, t: T, lbl: Label): SeqMem[T] = macro MemTransform.apply[T] + def apply[T <: Data](size: Int, t: T): SeqMem[T] = do_apply(size, t, UnknownLabel)(DeprecatedSourceInfo) - def do_apply[T <: Data](size: Int, t: T)(implicit sourceInfo: SourceInfo): SeqMem[T] = { + def do_apply[T <: Data](size: Int, t: T, lbl: Label)(implicit sourceInfo: SourceInfo): SeqMem[T] = { val mt = t.chiselCloneType Binding.bind(mt, NoDirectionBinder, "Error: fresh t") // TODO(twigg): Remove need for this Binding val mem = new SeqMem(mt, size) - pushCommand(DefSeqMemory(sourceInfo, mem, mt, size)) // TODO multi-clock + pushCommand(DefSeqMemory(sourceInfo, mem, mt, lbl, size)) // TODO multi-clock mem } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 579d688..b9848b6 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -257,8 +257,8 @@ case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command case class DefWire(sourceInfo: SourceInfo, id: Data, lbl: Label) extends Definition case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg, lbl: Label) extends Definition case class DefRegInit(sourceInfo: SourceInfo, id: Data, clock: Arg, reset: Arg, init: Arg, lbl: Label) 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 DefMemory(sourceInfo: SourceInfo, id: HasId, t: Data, lbl: Label, size: Int) extends Definition +case class DefSeqMemory(sourceInfo: SourceInfo, id: HasId, t: Data, lbl: Label, 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 diff --git a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala index fdeb22d..0b7de8c 100644 --- a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala +++ b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala @@ -54,8 +54,8 @@ class InstTransform(val c: Context) extends SourceInfoTransformMacro { class MemTransform(val c: Context) extends SourceInfoTransformMacro { import c.universe._ - def apply[T: c.WeakTypeTag](size: c.Tree, t: c.Tree): c.Tree = { - q"$thisObj.do_apply($size, $t)($implicitSourceInfo)" + def apply[T: c.WeakTypeTag](size: c.Tree, t: c.Tree, lbl: c.Tree): c.Tree = { + q"$thisObj.do_apply($size, $t, $lbl)($implicitSourceInfo)" } } diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 6e266c1..48a2e9b 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -35,8 +35,8 @@ private class Emitter(circuit: Circuit) { case e: DefWire => s"wire ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}" case e: DefReg => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}, ${e.clock.fullName(ctx)}" case e: DefRegInit => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))" - case e: DefMemory => s"cmem ${e.name} : ${e.t.toType}[${e.size}]" - case e: DefSeqMemory => s"smem ${e.name} : ${e.t.toType}[${e.size}]" + case e: DefMemory => s"cmem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType}[${e.size}]" + case e: DefSeqMemory => s"smem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType}[${e.size}]" case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}" case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}" case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}" diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index e1661b3..de6ae87 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -30,6 +30,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val Level = chisel3.core.Level val FunLabel = chisel3.core.FunLabel val HLevel = chisel3.core.HLevel + val VLabel = chisel3.core.VLabel val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse From 4387bcecf4e041c5fdd9e194a88d9fb427b88114 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 2 May 2017 12:56:45 -0400 Subject: [PATCH 02/35] Pathnames for exprs in bundles not in port decls --- src/main/scala/chisel3/internal/firrtl/Emitter.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 48a2e9b..3e185df 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -32,11 +32,11 @@ private class Emitter(circuit: Circuit) { case e: DefEndorse[_] => val lbl_s = e.lbl.fullName(ctx) s"node ${e.name} ${lbl_s} = endorse(${e.arg.fullName(ctx)}, ${lbl_s})" - case e: DefWire => s"wire ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}" - case e: DefReg => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}, ${e.clock.fullName(ctx)}" - case e: DefRegInit => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))" - case e: DefMemory => s"cmem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType}[${e.size}]" - case e: DefSeqMemory => s"smem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType}[${e.size}]" + case e: DefWire => s"wire ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}" + case e: DefReg => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}, ${e.clock.fullName(ctx)}" + case e: DefRegInit => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))" + case e: DefMemory => s"cmem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType(ctx)}[${e.size}]" + case e: DefSeqMemory => s"smem ${e.name} : ${e.lbl.fullName(ctx)}${e.t.toType(ctx)}[${e.size}]" case e: DefMemPort[_] => s"${e.dir} mport ${e.name} = ${e.source.fullName(ctx)}[${e.index.fullName(ctx)}], ${e.clock.fullName(ctx)}" case e: Connect => s"${e.loc.fullName(ctx)} <= ${e.exp.fullName(ctx)}" case e: BulkConnect => s"${e.loc1.fullName(ctx)} <- ${e.loc2.fullName(ctx)}" From 5f70c61ca13b6da9b70c0950c56077f3398b4159 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 2 May 2017 12:57:29 -0400 Subject: [PATCH 03/35] Interface for labeling DecoupledIOs --- src/main/scala/chisel3/util/Decoupled.scala | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 2e874a1..351f2e1 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -15,10 +15,10 @@ import chisel3.core.ExplicitCompileOptions.NotStrict * uses the flipped interface. Actual semantics of ready/valid are * enforced via use of concrete subclasses. */ -abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle +abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: Label=UnknownLabel) extends Bundle { - val ready = Input(Bool()) - val valid = Output(Bool()) + val ready = Input(Bool(), rdyl) + val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) } @@ -70,16 +70,17 @@ object ReadyValidIO { * to accept the data this cycle. No requirements are placed on the signaling * of ready or valid. */ -class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) +class DecoupledIO[+T <: Data](gen: T, rdyl: Label, vall: Label) extends ReadyValidIO[T](gen, rdyl, vall) { - override def cloneType: this.type = new DecoupledIO(gen).asInstanceOf[this.type] + override def cloneType: this.type = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] + def this(gen: T) = this(gen, UnknownLabel, UnknownLabel) } /** This factory adds a decoupled handshaking protocol to a data bundle. */ object Decoupled { /** Wraps some Data with a DecoupledIO interface. */ - def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) + def apply[T <: Data](gen: T, rdyl: Label = UnknownLabel, vall: Label = UnknownLabel): DecoupledIO[T] = new DecoupledIO(gen, rdyl, vall) /** Downconverts an IrrevocableIO output to a DecoupledIO, dropping guarantees of irrevocability. * From 1c002e1aae560dd3843f0340daeebe32e8d83707 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 9 May 2017 10:48:51 -0400 Subject: [PATCH 04/35] Label params for core components --- src/main/scala/chisel3/util/Arbiter.scala | 38 ++++++++++++++++------- src/main/scala/chisel3/util/Valid.scala | 7 +++-- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 7e049c9..3486aa0 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -15,10 +15,11 @@ import chisel3.core.ExplicitCompileOptions.NotStrict * @param gen data type * @param n number of inputs */ -class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { - val in = Flipped(Vec(n, Decoupled(gen))) - val out = Decoupled(gen) - val chosen = Output(UInt(log2Up(n).W)) +class ArbiterIO[T <: Data](gen: T, n: Int, inl: Label, outl: Label) extends Bundle { + val in = Flipped(Vec(n, Decoupled(gen, inl, inl))) + val out = Decoupled(gen, outl, outl) + val chosen = Output(UInt(log2Up(n).W), outl) + def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) } /** Arbiter Control determining which producer has access @@ -31,10 +32,11 @@ private object ArbiterCtrl { } } -abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool]) extends Module { +abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, + needsLock: Option[T => Bool], inl: Label, outl: Label) extends Module { protected def grant: Seq[Bool] protected def choice: UInt - val io = IO(new ArbiterIO(gen, n)) + val io = IO(new ArbiterIO(gen, n, inl, outl)) io.chosen := choice io.out.valid := io.in(io.chosen).valid @@ -58,10 +60,14 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo for ((in, g) <- io.in zip grant) in.ready := g && io.out.ready } + + def this(gen: T, n: Int, count: Int, needsLock: Option[T=>Bool]) + = this(gen, n, count, needsLock, UnknownLabel, UnknownLabel) } -class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) - extends LockingArbiterLike[T](gen, n, count, needsLock) { +class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, + inl: Label, outl: Label, needsLock: Option[T => Bool]) + extends LockingArbiterLike[T](gen, n, count, needsLock, inl, outl) { private lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) private lazy val grantMask = (0 until n).map(_.asUInt > lastGrant) private lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } @@ -76,15 +82,22 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ when (io.in(i).valid) { choice := i.asUInt } for (i <- n-1 to 1 by -1) when (validMask(i)) { choice := i.asUInt } + + def this(gen: T, n: Int, count: Int, needsLock: Option[T => Bool ] = None) = + this(gen, n, count, UnknownLabel, UnknownLabel, needsLock) } -class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) - extends LockingArbiterLike[T](gen, n, count, needsLock) { +class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, + inl: Label, outl: Label, needsLock: Option[T => Bool]) + extends LockingArbiterLike[T](gen, n, count, needsLock, inl, outl) { protected def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) override protected lazy val choice = Wire(init=(n-1).asUInt) for (i <- n-2 to 0 by -1) when (io.in(i).valid) { choice := i.asUInt } + + def this(gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) = + this(gen, n, count, UnknownLabel, UnknownLabel, needsLock) } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -97,7 +110,10 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T * consumer.io.in <> arb.io.out * }}} */ -class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) +class RRArbiter[T <: Data](gen:T, n: Int, inl: Label, outl: Label) + extends LockingRRArbiter[T](gen, n, 1, inl, outl, None) { + def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) +} /** Hardware module that is used to sequence n producers into 1 consumer. * Priority is given to lower producer. diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 0229b7f..8c46f77 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -10,17 +10,18 @@ import chisel3._ import chisel3.core.ExplicitCompileOptions.NotStrict /** An Bundle containing data and a signal determining if it is valid */ -class Valid[+T <: Data](gen: T) extends Bundle +class Valid[+T <: Data](gen: T, vall: Label) extends Bundle { - val valid = Output(Bool()) + val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) def fire(dummy: Int = 0): Bool = valid override def cloneType: this.type = Valid(gen).asInstanceOf[this.type] + def this(gen: T) = this(gen, UnknownLabel) } /** Adds a valid protocol to any interface */ object Valid { - def apply[T <: Data](gen: T): Valid[T] = new Valid(gen) + def apply[T <: Data](gen: T, vall: Label = UnknownLabel): Valid[T] = new Valid(gen) } /** A hardware module that delays data coming down the pipeline From 5a47314b141dbd6f6c379fc87384160d63147c1a Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 10 May 2017 13:04:55 -0400 Subject: [PATCH 05/35] Fix Valid. Sad hack for reflection-named dependands --- src/main/scala/chisel3/util/Decoupled.scala | 5 ++++- src/main/scala/chisel3/util/Valid.scala | 7 +++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 351f2e1..7a2c4e4 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -19,7 +19,10 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: { val ready = Input(Bool(), rdyl) val valid = Output(Bool(), vall) - val bits = Output(gen.chiselCloneType) + // Disappointing hack to get reflection-generated names + // to appear in dependent types constructed with the version + // of this thing where labels get down-propagated from the bits. + val bits = gen //Output(gen.chiselCloneType) } object ReadyValidIO { diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 8c46f77..2f0ea88 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -10,18 +10,17 @@ import chisel3._ import chisel3.core.ExplicitCompileOptions.NotStrict /** An Bundle containing data and a signal determining if it is valid */ -class Valid[+T <: Data](gen: T, vall: Label) extends Bundle +class Valid[+T <: Data](gen: T, vall: Label=UnknownLabel) extends Bundle { val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) def fire(dummy: Int = 0): Bool = valid - override def cloneType: this.type = Valid(gen).asInstanceOf[this.type] - def this(gen: T) = this(gen, UnknownLabel) + override def cloneType: this.type = Valid(gen, vall).asInstanceOf[this.type] } /** Adds a valid protocol to any interface */ object Valid { - def apply[T <: Data](gen: T, vall: Label = UnknownLabel): Valid[T] = new Valid(gen) + def apply[T <: Data](gen: T, lbl: Label=UnknownLabel): Valid[T] = new Valid(gen, lbl) } /** A hardware module that delays data coming down the pipeline From 6498046edb926ecff84b659a98f5fa5d63d8e0fd Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 18 May 2017 15:06:50 -0400 Subject: [PATCH 06/35] Dependands get reflection-named after cloneType... This seems very hacky to me, but I can build the emulator now. I spent a bunch of hours trying to come up with a less hacky solution, but I give up for now. --- .../main/scala/chisel3/core/Aggregate.scala | 18 +++++++++-- .../src/main/scala/chisel3/core/Bits.scala | 32 +++++++++++++++---- .../src/main/scala/chisel3/core/Data.scala | 4 +++ .../src/main/scala/chisel3/core/Label.scala | 26 +++++++++++---- .../main/scala/chisel3/internal/Builder.scala | 18 +++++++++-- src/main/scala/chisel3/util/Decoupled.scala | 12 +++++-- 6 files changed, 91 insertions(+), 19 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 00cf254..8164fc2 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -10,6 +10,7 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ +import scala.collection.mutable.HashSet /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -474,11 +475,15 @@ class Bundle extends Record { val constructor = this.getClass.getConstructors.head try { val args = Seq.fill(constructor.getParameterTypes.size)(null) - constructor.newInstance(args:_*).asInstanceOf[this.type] + val ret = constructor.newInstance(args:_*).asInstanceOf[this.type] + copyIDs(ret) + ret } catch { case e: java.lang.reflect.InvocationTargetException if e.getCause.isInstanceOf[java.lang.NullPointerException] => try { - constructor.newInstance(_parent.get).asInstanceOf[this.type] + val ret = constructor.newInstance(_parent.get).asInstanceOf[this.type] + copyIDs(ret) + ret } catch { case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + @@ -491,6 +496,15 @@ class Bundle extends Record { } } + override def copyIDs(newOne: this.type): Unit = { + for( (name, elt) <- elements ) { + // newOne.elements(name).sharedIDs = elt.sharedIDs + elt.copyIDs(newOne.elements(name).asInstanceOf[elt.type]) + newOne.elements(name).lbl_ = elt.lbl_ + } + } + + /** Default "pretty-print" implementation * Analogous to printing a Map * Results in "Bundle(elt0.name -> elt0.value, ...)" diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 2654359..1435d54 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -12,6 +12,7 @@ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfo import chisel3.internal.firrtl.PrimOp._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict +import scala.collection.mutable.HashSet /** Element is a leaf data type: it cannot contain other Data objects. Example * uses are for representing primitive data types, like integers and bits. @@ -390,8 +391,12 @@ abstract trait Num[T <: Data] { sealed class UInt private[core] (width: Width, lit: Option[ULit] = None) extends Bits(width, lit) with Num[UInt] { - private[core] override def cloneTypeWidth(w: Width): this.type = - new UInt(w).asInstanceOf[this.type] + private[core] override def cloneTypeWidth(w: Width): this.type = { + val ret = new UInt(w).asInstanceOf[this.type] + //ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) + copyIDs(ret) + ret + } private[chisel3] def toType = s"UInt$width" // TODO: refactor to share documentation with Num or add independent scaladoc @@ -561,8 +566,12 @@ object Bits extends UIntFactory sealed class SInt private[core] (width: Width, lit: Option[SLit] = None) extends Bits(width, lit) with Num[SInt] { - private[core] override def cloneTypeWidth(w: Width): this.type = - new SInt(w).asInstanceOf[this.type] + private[core] override def cloneTypeWidth(w: Width): this.type = { + val ret : this.type = new SInt(w).asInstanceOf[this.type] + //ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) + copyIDs(ret) + ret + } private[chisel3] def toType = s"SInt$width" final def unary_- (): SInt = macro SourceInfoTransform.noArg @@ -713,7 +722,11 @@ object SInt extends SIntFactory sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) { private[core] override def cloneTypeWidth(w: Width): this.type = { require(!w.known || w.get == 1) - new Bool().asInstanceOf[this.type] + val ret = new Bool().asInstanceOf[this.type] + // ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) + // ret.sharedIDs = this.sharedIDs + copyIDs(ret) + ret } // REVIEW TODO: Why does this need to exist and have different conventions @@ -851,8 +864,13 @@ object Mux { */ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit: Option[FPLit] = None) extends Bits(width, lit) with Num[FixedPoint] { - private[core] override def cloneTypeWidth(w: Width): this.type = - new FixedPoint(w, binaryPoint).asInstanceOf[this.type] + private[core] override def cloneTypeWidth(w: Width): this.type = { + val ret = new FixedPoint(w, binaryPoint).asInstanceOf[this.type] + // ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) + // ret.sharedIDs = this.sharedIDs + copyIDs(ret) + ret + } private[chisel3] def toType = s"Fixed$width$binaryPoint" def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 1e3516d..dc2358d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -9,6 +9,7 @@ import chisel3.internal.Builder.{pushCommand, pushOp} import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ import chisel3.internal.firrtl.PrimOp.AsUIntOp +import scala.collection.mutable.HashSet sealed abstract class Direction(name: String) { override def toString: String = name @@ -219,6 +220,9 @@ abstract class Data extends HasId with HasLabel{ Data.setFirrtlDirection(clone_elem, Data.getFirrtlDirection(source_elem)) } } + // clone.sharedIDs = this.sharedIDs // HashSet(this.sharedIDs.toSeq:_*) + copyIDs(clone) + clone.lbl_ = lbl_ clone } final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index c846271..89e0afb 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -53,9 +53,29 @@ object FunLabel{ def apply(fname: String, ids: HasId*) = new FunLabel(fname, ids.toList) } + +/* +class HLevel(var id: HasId) extends LabelComp { + def name = s"[[${id.getRef.name}]]H" + def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" + override def equals(that: Any) = that match { + case lx: HLevel => lx.id == id + case _ => false + } + id.listeningLabels += this + println(s"${this.toString} listening to ${id.toString}") +} + +object HLevel { + def apply(id: HasId) = new HLevel(id) + def unapply(l: HLevel) = Some(l.id) +} +*/ + case class HLevel(id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]H" def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" + id.sharedIDs += id } case class VLabel(id: HasId) extends LabelComp { @@ -66,18 +86,12 @@ case class VLabel(id: HasId) extends LabelComp { object C { def apply(l: Label): LabelComp = l match { case Label(conf, _) => conf - case _ => - throw new Exception("tried to conf project Bundle") - UnknownLabelComp } } object I { def apply(l: Label): LabelComp = l match { case Label(_, integ) => integ - case _ => - throw new Exception("tried to integ project Bundle") - UnknownLabelComp } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 26beb6b..daaa4de 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -3,7 +3,7 @@ package chisel3.internal import scala.util.DynamicVariable -import scala.collection.mutable.{ArrayBuffer, HashMap} +import scala.collection.mutable.{ArrayBuffer, HashMap,Set} import chisel3._ import core._ @@ -78,6 +78,13 @@ private[chisel3] trait HasId extends InstanceId { case _ => false } + // This is used so that clones don't prevent expressions in labels from + // getting the right name + private[chisel3] var sharedIDs = new scala.collection.mutable.HashSet[HasId]() + + def copyIDs(that:this.type): Unit = + that.sharedIDs = sharedIDs + // 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 @@ -101,7 +108,14 @@ private[chisel3] trait HasId extends InstanceId { } private var _ref: Option[Arg] = None - private[chisel3] def setRef(imm: Arg): Unit = _ref = Some(imm) + def idGood(ref: Option[Arg]) = !(_ref.isEmpty || (_ref.get.name contains "_T_")) + private[chisel3] def setRef(imm: Arg): Unit = { + _ref = Some(imm) + (sharedIDs - this) foreach { thatId => + //if(idGood(_ref) && !idGood(thatId._ref)) thatId.setRef(imm) + if(_ref != thatId._ref) thatId.setRef(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)) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 7a2c4e4..e8707e5 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -22,7 +22,7 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: // Disappointing hack to get reflection-generated names // to appear in dependent types constructed with the version // of this thing where labels get down-propagated from the bits. - val bits = gen //Output(gen.chiselCloneType) + val bits = Output(gen.chiselCloneType) } object ReadyValidIO { @@ -75,7 +75,15 @@ object ReadyValidIO { */ class DecoupledIO[+T <: Data](gen: T, rdyl: Label, vall: Label) extends ReadyValidIO[T](gen, rdyl, vall) { - override def cloneType: this.type = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] + override def cloneType: this.type = { + val ret = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] + // println(s"this ids: ${this.sharedIDs.toString}") + // println(s"this.gen ids: ${gen.sharedIDs.toString}") + // println(s"this.bits ids: ${bits.sharedIDs.toString}") + copyIDs(ret) + bits.copyIDs(ret.bits) + ret + } def this(gen: T) = this(gen, UnknownLabel, UnknownLabel) } From 3c71c1e7a5e7b8d785e4a80deeb2535816d1df2e Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Fri, 19 May 2017 13:21:29 -0400 Subject: [PATCH 07/35] Optionally emit body of just top --- .../chisel3/ChiselExecutionOptions.scala | 10 +++++- src/main/scala/chisel3/Driver.scala | 10 +++--- .../chisel3/internal/firrtl/Emitter.scala | 32 +++++++++++++++++-- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/main/scala/chisel3/ChiselExecutionOptions.scala b/src/main/scala/chisel3/ChiselExecutionOptions.scala index 6f58153..4a9cf95 100644 --- a/src/main/scala/chisel3/ChiselExecutionOptions.scala +++ b/src/main/scala/chisel3/ChiselExecutionOptions.scala @@ -13,7 +13,8 @@ import firrtl.{ExecutionOptionsManager, ComposableOptions} * @note this extends FirrtlExecutionOptions which extends CommonOptions providing easy access to down chain options */ case class ChiselExecutionOptions( - runFirrtlCompiler: Boolean = true + runFirrtlCompiler: Boolean = true, + compileTopOnly: Boolean = false // var runFirrtlAsProcess: Boolean = false ) extends ComposableOptions @@ -30,5 +31,12 @@ trait HasChiselExecutionOptions { chiselOptions = chiselOptions.copy(runFirrtlCompiler = false) } .text("Stop after chisel emits chirrtl file") + + parser.opt[Unit]("top-def-only") + .abbr("tdf") + .foreach { _ => + chiselOptions = chiselOptions.copy(compileTopOnly = true) + } + .text("Only emit the def of the top-level module to support modular label-checking") } diff --git a/src/main/scala/chisel3/Driver.scala b/src/main/scala/chisel3/Driver.scala index 7bdb4d6..8b9a2b6 100644 --- a/src/main/scala/chisel3/Driver.scala +++ b/src/main/scala/chisel3/Driver.scala @@ -90,14 +90,14 @@ object Driver extends BackendCompilationUtilities { */ def elaborate[T <: Module](gen: () => T): Circuit = internal.Builder.build(Module(gen())) - def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen)) + def emit[T <: Module](gen: () => T): String = Emitter.emit(elaborate(gen), false) - def emit[T <: Module](ir: Circuit): String = Emitter.emit(ir) + def emit[T <: Module](ir: Circuit): String = Emitter.emit(ir, false) - def dumpFirrtl(ir: Circuit, optName: Option[File]): File = { + def dumpFirrtl(ir: Circuit, optName: Option[File], onlyTop: Boolean = false): File = { val f = optName.getOrElse(new File(ir.name + ".fir")) val w = new FileWriter(f) - w.write(Emitter.emit(ir)) + w.write(Emitter.emit(ir, onlyTop)) w.close() f } @@ -132,7 +132,7 @@ object Driver extends BackendCompilationUtilities { val chiselOptions = optionsManager.chiselOptions // use input because firrtl will be reading this - val firrtlString = Emitter.emit(circuit) + val firrtlString = Emitter.emit(circuit, chiselOptions.compileTopOnly) val firrtlFileName = firrtlOptions.getInputFileName(optionsManager) val firrtlFile = new File(firrtlFileName) diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 3e185df..5937067 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -14,10 +14,10 @@ import chisel3.core.HLevel import chisel3.core.Data private[chisel3] object Emitter { - def emit(circuit: Circuit): String = new Emitter(circuit).toString + def emit(circuit: Circuit, compileTopOnly: Boolean): String = new Emitter(circuit, compileTopOnly).toString } -private class Emitter(circuit: Circuit) { +private class Emitter(circuit: Circuit, compileTopOnly: Boolean) { override def toString: String = res.toString private def emitPort(e: Port, ctx:Component): String = @@ -98,6 +98,16 @@ private class Emitter(circuit: Circuit) { body.toString() } + private def modulePorts(m: Component): String = { + val body = new StringBuilder + withIndent { + for (p <- m.ports) + body ++= newline + emitPort(p,m) + body ++= newline + } + body.toString() + } + /** Returns the FIRRTL declaration and body of a module, or nothing if it's a * duplicate of something already emitted (on the basis of simple string * matching). @@ -110,6 +120,14 @@ private class Emitter(circuit: Circuit) { sb.result } + private def emitDecl(m: Component): String = { + // Emit just the declaration and ports for modular label-checking. + val sb = new StringBuilder + sb.append(moduleDecl(m)) + sb.append(modulePorts(m)) + sb.result + } + private var indentLevel = 0 private def newline = "\n" + (" " * indentLevel) private def indent(): Unit = indentLevel += 1 @@ -119,6 +137,14 @@ private class Emitter(circuit: Circuit) { private val res = new StringBuilder() res ++= s";${Driver.chiselVersionString}\n" res ++= s"circuit ${circuit.name} : " - withIndent { circuit.components.foreach(c => res ++= emit(c)) } + if(compileTopOnly) { + withIndent { circuit.components.foreach(c => + if(c.name == circuit.name) res ++= emit(c) + else res ++= emitDecl(c) + ) + } + } else { + withIndent { circuit.components.foreach(c => res ++= emit(c)) } + } res ++= newline } From 85345c1ab2dce2788c44117ade9c4ef8a4cb67f3 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 23 May 2017 15:14:24 -0400 Subject: [PATCH 08/35] labels in chisel2-3 compatibility layer --- src/main/scala/chisel3/compatibility.scala | 37 +++++++++++++++++----- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index d338d9a..bca46da 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -14,6 +14,26 @@ package object Chisel { // scalastyle:ignore package.object.name implicit val defaultCompileOptions = chisel3.core.ExplicitCompileOptions.NotStrict type Direction = chisel3.core.Direction + type Label = chisel3.core.Label + val Label = chisel3.core.Label + val UnknownLabel = chisel3.core.UnknownLabel + val UnknownLabelComp = chisel3.core.UnknownLabelComp + val Level = chisel3.core.Level + val FunLabel = chisel3.core.FunLabel + val HLevel = chisel3.core.HLevel + val VLabel = chisel3.core.VLabel + val Declassify = chisel3.core.Declassify + val Endorse = chisel3.core.Endorse + + + // Not originally part of compatibility.scala + val Input = chisel3.core.Input + val Output = chisel3.core.Output + + // Components + val C = chisel3.core.C + val I = chisel3.core.I + val INPUT = chisel3.core.Direction.Input val OUTPUT = chisel3.core.Direction.Output val NODIR = chisel3.core.Direction.Unspecified @@ -71,11 +91,12 @@ package object Chisel { // scalastyle:ignore package.object.name def apply(dir: Direction, width: Int): UInt = apply(dir, width.W) /** Create a UInt with a specified direction, but unspecified width - compatibility with Chisel2. */ def apply(dir: Direction): UInt = apply(dir, Width()) - def apply(dir: Direction, width: Width): UInt = { - val result = apply(width) + def apply(dir: Direction, width: Width): UInt = apply(dir, width, UnknownLabel) + def apply(dir: Direction, width: Width, lbl:Label): UInt = { + val result = apply(width, lbl) dir match { - case chisel3.core.Direction.Input => chisel3.core.Input(result) - case chisel3.core.Direction.Output => chisel3.core.Output(result) + case chisel3.core.Direction.Input => chisel3.core.Input(result, lbl) + case chisel3.core.Direction.Output => chisel3.core.Output(result, lbl) case chisel3.core.Direction.Unspecified => result } } @@ -130,11 +151,11 @@ package object Chisel { // scalastyle:ignore package.object.name def apply(x: Boolean): Bool = x.B /** Create a UInt with a specified direction and width - compatibility with Chisel2. */ - def apply(dir: Direction): Bool = { - val result = apply() + def apply(dir: Direction, lbl:Label=UnknownLabel): Bool = { + val result = apply(lbl) dir match { - case chisel3.core.Direction.Input => chisel3.core.Input(result) - case chisel3.core.Direction.Output => chisel3.core.Output(result) + case chisel3.core.Direction.Input => chisel3.core.Input(result, lbl) + case chisel3.core.Direction.Output => chisel3.core.Output(result, lbl) case chisel3.core.Direction.Unspecified => result } } From 8d3a230ee8e8ce114b318b1ae7cb59267b824378 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 23 May 2017 15:43:24 -0400 Subject: [PATCH 09/35] Revert "Dependands get reflection-named after cloneType..." This reverts commit 6498046edb926ecff84b659a98f5fa5d63d8e0fd. --- .../main/scala/chisel3/core/Aggregate.scala | 18 ++--------- .../src/main/scala/chisel3/core/Bits.scala | 32 ++++--------------- .../src/main/scala/chisel3/core/Data.scala | 4 --- .../src/main/scala/chisel3/core/Label.scala | 26 ++++----------- .../main/scala/chisel3/internal/Builder.scala | 18 ++--------- src/main/scala/chisel3/util/Decoupled.scala | 12 ++----- 6 files changed, 19 insertions(+), 91 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 8164fc2..00cf254 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -10,7 +10,6 @@ import chisel3.internal._ import chisel3.internal.Builder.pushCommand import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ -import scala.collection.mutable.HashSet /** An abstract class for data types that solely consist of (are an aggregate * of) other Data objects. @@ -475,15 +474,11 @@ class Bundle extends Record { val constructor = this.getClass.getConstructors.head try { val args = Seq.fill(constructor.getParameterTypes.size)(null) - val ret = constructor.newInstance(args:_*).asInstanceOf[this.type] - copyIDs(ret) - ret + constructor.newInstance(args:_*).asInstanceOf[this.type] } catch { case e: java.lang.reflect.InvocationTargetException if e.getCause.isInstanceOf[java.lang.NullPointerException] => try { - val ret = constructor.newInstance(_parent.get).asInstanceOf[this.type] - copyIDs(ret) - ret + constructor.newInstance(_parent.get).asInstanceOf[this.type] } catch { case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + @@ -496,15 +491,6 @@ class Bundle extends Record { } } - override def copyIDs(newOne: this.type): Unit = { - for( (name, elt) <- elements ) { - // newOne.elements(name).sharedIDs = elt.sharedIDs - elt.copyIDs(newOne.elements(name).asInstanceOf[elt.type]) - newOne.elements(name).lbl_ = elt.lbl_ - } - } - - /** Default "pretty-print" implementation * Analogous to printing a Map * Results in "Bundle(elt0.name -> elt0.value, ...)" diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 1435d54..2654359 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -12,7 +12,6 @@ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfo import chisel3.internal.firrtl.PrimOp._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict -import scala.collection.mutable.HashSet /** Element is a leaf data type: it cannot contain other Data objects. Example * uses are for representing primitive data types, like integers and bits. @@ -391,12 +390,8 @@ abstract trait Num[T <: Data] { sealed class UInt private[core] (width: Width, lit: Option[ULit] = None) extends Bits(width, lit) with Num[UInt] { - private[core] override def cloneTypeWidth(w: Width): this.type = { - val ret = new UInt(w).asInstanceOf[this.type] - //ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) - copyIDs(ret) - ret - } + private[core] override def cloneTypeWidth(w: Width): this.type = + new UInt(w).asInstanceOf[this.type] private[chisel3] def toType = s"UInt$width" // TODO: refactor to share documentation with Num or add independent scaladoc @@ -566,12 +561,8 @@ object Bits extends UIntFactory sealed class SInt private[core] (width: Width, lit: Option[SLit] = None) extends Bits(width, lit) with Num[SInt] { - private[core] override def cloneTypeWidth(w: Width): this.type = { - val ret : this.type = new SInt(w).asInstanceOf[this.type] - //ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) - copyIDs(ret) - ret - } + private[core] override def cloneTypeWidth(w: Width): this.type = + new SInt(w).asInstanceOf[this.type] private[chisel3] def toType = s"SInt$width" final def unary_- (): SInt = macro SourceInfoTransform.noArg @@ -722,11 +713,7 @@ object SInt extends SIntFactory sealed class Bool(lit: Option[ULit] = None) extends UInt(1.W, lit) { private[core] override def cloneTypeWidth(w: Width): this.type = { require(!w.known || w.get == 1) - val ret = new Bool().asInstanceOf[this.type] - // ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) - // ret.sharedIDs = this.sharedIDs - copyIDs(ret) - ret + new Bool().asInstanceOf[this.type] } // REVIEW TODO: Why does this need to exist and have different conventions @@ -864,13 +851,8 @@ object Mux { */ sealed class FixedPoint private (width: Width, val binaryPoint: BinaryPoint, lit: Option[FPLit] = None) extends Bits(width, lit) with Num[FixedPoint] { - private[core] override def cloneTypeWidth(w: Width): this.type = { - val ret = new FixedPoint(w, binaryPoint).asInstanceOf[this.type] - // ret.sharedIDs = HashSet(this.sharedIDs.toSeq:_*) - // ret.sharedIDs = this.sharedIDs - copyIDs(ret) - ret - } + private[core] override def cloneTypeWidth(w: Width): this.type = + new FixedPoint(w, binaryPoint).asInstanceOf[this.type] private[chisel3] def toType = s"Fixed$width$binaryPoint" def := (that: Data)(implicit sourceInfo: SourceInfo): Unit = that match { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index dc2358d..1e3516d 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -9,7 +9,6 @@ import chisel3.internal.Builder.{pushCommand, pushOp} import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo._ import chisel3.internal.firrtl.PrimOp.AsUIntOp -import scala.collection.mutable.HashSet sealed abstract class Direction(name: String) { override def toString: String = name @@ -220,9 +219,6 @@ abstract class Data extends HasId with HasLabel{ Data.setFirrtlDirection(clone_elem, Data.getFirrtlDirection(source_elem)) } } - // clone.sharedIDs = this.sharedIDs // HashSet(this.sharedIDs.toSeq:_*) - copyIDs(clone) - clone.lbl_ = lbl_ clone } final def := (that: Data)(implicit sourceInfo: SourceInfo, connectionCompileOptions: CompileOptions): Unit = this.connect(that)(sourceInfo, connectionCompileOptions) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index 89e0afb..c846271 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -53,29 +53,9 @@ object FunLabel{ def apply(fname: String, ids: HasId*) = new FunLabel(fname, ids.toList) } - -/* -class HLevel(var id: HasId) extends LabelComp { - def name = s"[[${id.getRef.name}]]H" - def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" - override def equals(that: Any) = that match { - case lx: HLevel => lx.id == id - case _ => false - } - id.listeningLabels += this - println(s"${this.toString} listening to ${id.toString}") -} - -object HLevel { - def apply(id: HasId) = new HLevel(id) - def unapply(l: HLevel) = Some(l.id) -} -*/ - case class HLevel(id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]H" def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" - id.sharedIDs += id } case class VLabel(id: HasId) extends LabelComp { @@ -86,12 +66,18 @@ case class VLabel(id: HasId) extends LabelComp { object C { def apply(l: Label): LabelComp = l match { case Label(conf, _) => conf + case _ => + throw new Exception("tried to conf project Bundle") + UnknownLabelComp } } object I { def apply(l: Label): LabelComp = l match { case Label(_, integ) => integ + case _ => + throw new Exception("tried to integ project Bundle") + UnknownLabelComp } } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index daaa4de..26beb6b 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -3,7 +3,7 @@ package chisel3.internal import scala.util.DynamicVariable -import scala.collection.mutable.{ArrayBuffer, HashMap,Set} +import scala.collection.mutable.{ArrayBuffer, HashMap} import chisel3._ import core._ @@ -78,13 +78,6 @@ private[chisel3] trait HasId extends InstanceId { case _ => false } - // This is used so that clones don't prevent expressions in labels from - // getting the right name - private[chisel3] var sharedIDs = new scala.collection.mutable.HashSet[HasId]() - - def copyIDs(that:this.type): Unit = - that.sharedIDs = sharedIDs - // 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 @@ -108,14 +101,7 @@ private[chisel3] trait HasId extends InstanceId { } private var _ref: Option[Arg] = None - def idGood(ref: Option[Arg]) = !(_ref.isEmpty || (_ref.get.name contains "_T_")) - private[chisel3] def setRef(imm: Arg): Unit = { - _ref = Some(imm) - (sharedIDs - this) foreach { thatId => - //if(idGood(_ref) && !idGood(thatId._ref)) thatId.setRef(imm) - if(_ref != thatId._ref) thatId.setRef(imm) - } - } + 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)) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index e8707e5..7a2c4e4 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -22,7 +22,7 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: // Disappointing hack to get reflection-generated names // to appear in dependent types constructed with the version // of this thing where labels get down-propagated from the bits. - val bits = Output(gen.chiselCloneType) + val bits = gen //Output(gen.chiselCloneType) } object ReadyValidIO { @@ -75,15 +75,7 @@ object ReadyValidIO { */ class DecoupledIO[+T <: Data](gen: T, rdyl: Label, vall: Label) extends ReadyValidIO[T](gen, rdyl, vall) { - override def cloneType: this.type = { - val ret = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] - // println(s"this ids: ${this.sharedIDs.toString}") - // println(s"this.gen ids: ${gen.sharedIDs.toString}") - // println(s"this.bits ids: ${bits.sharedIDs.toString}") - copyIDs(ret) - bits.copyIDs(ret.bits) - ret - } + override def cloneType: this.type = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] def this(gen: T) = this(gen, UnknownLabel, UnknownLabel) } From b9fc420fec078dcb5a18c8fc25ffecfa66a6c5e6 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 23 May 2017 19:00:32 -0400 Subject: [PATCH 10/35] An unhacky solution to dependent variable naming. --- .../main/scala/chisel3/core/Aggregate.scala | 23 +++++++++++++++++++ .../main/scala/chisel3/internal/Builder.scala | 1 + src/main/scala/chisel3/util/Decoupled.scala | 7 +++--- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 00cf254..cb8303e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -394,6 +394,29 @@ abstract class Record extends Aggregate { // which can cause collisions val _namespace = Namespace.empty for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name)) } + + def strTmp(s:String) = s contains "_T_" + def argIsTemp(arg: Arg): Boolean = arg match { + case ax: Ref => strTmp(ax.name) + case ax: ModuleIO => strTmp(ax.name) || !ax.mod.refSet ||strTmp(ax.mod.getRef.name) + case ax: Slot => !ax.imm.id.refSet || argIsTemp(ax.imm.id.getRef) || strTmp(ax.name) + case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) + case ax: Node => !ax.id.refSet || strTmp(ax.name) + case ax: LitArg => false + } + + for((name, elt) <- elements) { + elt.lbl.conf match { + case lx: HLevel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) + case lx: VLabel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) + case lx => + } + elt.lbl.integ match { + case lx: HLevel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) + case lx: VLabel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) + case lx => + } + } } private[chisel3] final def allElements: Seq[Element] = elements.toIndexedSeq.flatMap(_._2.allElements) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 26beb6b..023a4ea 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -106,6 +106,7 @@ private[chisel3] trait HasId extends InstanceId { 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[chisel3] def refSet: Boolean = !_ref.isEmpty // Implementation of public methods. def instanceName: String = _parent match { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 7a2c4e4..33fe5c7 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -9,6 +9,8 @@ import chisel3._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict +import chisel3.core.{HLevel, VLabel} + /** An I/O Bundle containing 'valid' and 'ready' signals that handshake * the transfer of data stored in the 'bits' subfield. * The base protocol implied by the directionality is that the consumer @@ -19,10 +21,7 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: { val ready = Input(Bool(), rdyl) val valid = Output(Bool(), vall) - // Disappointing hack to get reflection-generated names - // to appear in dependent types constructed with the version - // of this thing where labels get down-propagated from the bits. - val bits = gen //Output(gen.chiselCloneType) + val bits = Output(gen.chiselCloneType) } object ReadyValidIO { From a5e941a80f3c87d3a695f0875d15533bc4609698 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 24 May 2017 17:32:07 -0400 Subject: [PATCH 11/35] More dep label emit fixes --- .../main/scala/chisel3/core/Aggregate.scala | 72 +++++++++++++------ .../src/main/scala/chisel3/core/Data.scala | 4 ++ .../scala/chisel3/internal/firrtl/IR.scala | 12 +++- src/main/scala/chisel3/util/Decoupled.scala | 45 +++++++++++- 4 files changed, 109 insertions(+), 24 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index cb8303e..338479e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -244,6 +244,9 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) } private[chisel3] def toType: String = s"${sample_element.toType}[$length]" + private[chisel3] override def toType(ctx: Component): String = { + s"${sample_element.toType(ctx)}[$length]" + } private[chisel3] lazy val flatten: IndexedSeq[Bits] = (0 until length).flatMap(i => this.apply(i).flatten) @@ -386,6 +389,16 @@ abstract class Record extends Aggregate { } private[chisel3] lazy val flatten = elements.toIndexedSeq.flatMap(_._2.flatten) + + def strTmp(s:String) = s contains "_T_" + def argIsTemp(arg: Arg): Boolean = arg match { + case ax: Ref => strTmp(ax.name) + case ax: ModuleIO => strTmp(ax.name) || strTmp(ax.mod.name) + case ax: Slot => !ax.imm.id.refSet || argIsTemp(ax.imm.id.getRef) || strTmp(ax.name) + case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) + case ax: Node => !ax.id.refSet || strTmp(ax.name) + case ax: LitArg => false + } // NOTE: This sets up dependent references, it can be done before closing the Module private[chisel3] override def _onModuleClose: Unit = { // scalastyle:ignore method.name @@ -393,30 +406,34 @@ abstract class Record extends Aggregate { // identifier; however, Namespace sanitizes identifiers to make them legal for Firrtl/Verilog // which can cause collisions val _namespace = Namespace.empty - for ((name, elt) <- elements) { elt.setRef(this, _namespace.name(name)) } - - def strTmp(s:String) = s contains "_T_" - def argIsTemp(arg: Arg): Boolean = arg match { - case ax: Ref => strTmp(ax.name) - case ax: ModuleIO => strTmp(ax.name) || !ax.mod.refSet ||strTmp(ax.mod.getRef.name) - case ax: Slot => !ax.imm.id.refSet || argIsTemp(ax.imm.id.getRef) || strTmp(ax.name) - case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) - case ax: Node => !ax.id.refSet || strTmp(ax.name) - case ax: LitArg => false + + for ((name, elt) <- elements.toIndexedSeq.reverse) { + elt.setRef(this, _namespace.name(name)) } - for((name, elt) <- elements) { - elt.lbl.conf match { - case lx: HLevel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) - case lx => - } - elt.lbl.integ match { - case lx: HLevel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel => if(argIsTemp(lx.id.getRef)) lx.id.setRef(this, lx.id.getRef.name) - case lx => + for ((name, elt) <- elements.toIndexedSeq.reverse) { + if(elt.lbl != null) { + elt.lbl.conf match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) + lx.id.setRef(this, lx.id.getRef.name) + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) + lx.id.setRef(this, lx.id.getRef.name) + case lx => + } + elt.lbl.integ match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) + lx.id.setRef(this, lx.id.getRef.name) + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) + lx.id.setRef(this, lx.id.getRef.name) + case lx => + } } } + } private[chisel3] final def allElements: Seq[Element] = elements.toIndexedSeq.flatMap(_._2.allElements) @@ -497,11 +514,15 @@ class Bundle extends Record { val constructor = this.getClass.getConstructors.head try { val args = Seq.fill(constructor.getParameterTypes.size)(null) - constructor.newInstance(args:_*).asInstanceOf[this.type] + val ret = constructor.newInstance(args:_*).asInstanceOf[this.type] + cpy_lbls(ret) + ret } catch { case e: java.lang.reflect.InvocationTargetException if e.getCause.isInstanceOf[java.lang.NullPointerException] => try { - constructor.newInstance(_parent.get).asInstanceOf[this.type] + val ret = constructor.newInstance(_parent.get).asInstanceOf[this.type] + cpy_lbls(ret) + ret } catch { case _: java.lang.reflect.InvocationTargetException | _: java.lang.IllegalArgumentException => Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method. You are probably using " + @@ -514,6 +535,13 @@ class Bundle extends Record { } } + override def cpy_lbls(that: this.type): Unit = { + // for ((name, elt) <- elements) { + // elt.cpy_lbls(that.elements(name).asInstanceOf[elt.type]) + // // that.elements(name).lbl_ = elt.lbl_ + // } + } + /** Default "pretty-print" implementation * Analogous to printing a Map * Results in "Bundle(elt0.name -> elt0.value, ...)" diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 1e3516d..0fa18a2 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -193,6 +193,10 @@ abstract class Data extends HasId with HasLabel{ private[core] def width: Width private[core] def legacyConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit + private[chisel3] def cpy_lbls(that: this.type): Unit = { + that.lbl_ = lbl_ + } + /** cloneType must be defined for any Chisel object extending Data. * It is responsible for constructing a basic copy of the object being cloned. * If cloneType needs to recursively clone elements of an object, it should call diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index b9848b6..e66e233 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -52,11 +52,13 @@ object PrimOp { abstract class Arg { def fullName(ctx: Component): String = name def name: String + def pprint: String } case class Node(id: HasId) extends Arg { override def fullName(ctx: Component): String = id.getRef.fullName(ctx) def name: String = id.getRef.name + def pprint = s"Node(${id.getRef.pprint})" } abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { @@ -68,10 +70,12 @@ abstract class LitArg(val num: BigInt, widthArg: Width) extends Arg { require(widthArg.get >= minWidth, s"The literal value ${num} was elaborated with a specified width of ${widthArg.get} bits, but at least ${minWidth} bits are required.") } + def pprint = s"LitArg(${num}, ${widthArg})" } case class ILit(n: BigInt) extends Arg { def name: String = n.toString + def pprint = s"ILit(${n})" } case class ULit(n: BigInt, w: Width) extends LitArg(n, w) { @@ -97,18 +101,23 @@ case class FPLit(n: BigInt, w: Width, binaryPoint: BinaryPoint) extends LitArg(n def minWidth: Int = 1 + n.bitLength } -case class Ref(name: String) extends Arg +case class Ref(name: String) extends Arg { + def pprint = s"Ref(${name})" +} 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" + def pprint = s"ModuleIO(${mod.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}" + def pprint = s"Slot(${imm.pprint}, ${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)}]" + def pprint = s"Index(${imm.name}, ${value.name})" } sealed trait Bound @@ -273,6 +282,7 @@ abstract class Component extends Arg { def id: Module def name: String def ports: Seq[Port] + def pprint = s"Component(${id.name}, ${name}, ...)" } case class DefModule(id: Module, name: String, ports: Seq[Port], commands: Seq[Command]) extends Component case class DefBlackBox(id: Module, name: String, ports: Seq[Port], params: Map[String, Param]) extends Component diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 33fe5c7..380baf8 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -22,6 +22,44 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: val ready = Input(Bool(), rdyl) val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) + override def _onModuleClose: Unit = { + super._onModuleClose + bits match { + case bx: Record => + for ((name, elt) <- elements.toIndexedSeq.reverse) { + println(s"elt: $name") + println(s"pprint elt: ${elt.getRef.pprint}") + if(elt.lbl != null) { + elt.lbl.conf match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) { + println("found name in bits") + lx.id.setRef(bx, lx.id.getRef.name) + println(lx.toString) + println(s"pprint: ${lx.id.getRef.pprint}") + println(lx.name) + } + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx => + } + elt.lbl.integ match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx => + } + } + } + case _ => + println("bits is not a record") + } + + } } object ReadyValidIO { @@ -74,7 +112,12 @@ object ReadyValidIO { */ class DecoupledIO[+T <: Data](gen: T, rdyl: Label, vall: Label) extends ReadyValidIO[T](gen, rdyl, vall) { - override def cloneType: this.type = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] + override def cloneType: this.type = { + val ret = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] + cpy_lbls(ret) + bits.cpy_lbls(ret.bits) + ret + } def this(gen: T) = this(gen, UnknownLabel, UnknownLabel) } From ee10345323c82045920eff40aa4a39a899a41452 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 25 May 2017 13:32:59 -0400 Subject: [PATCH 12/35] Fix for veclabel deptype printing --- .../src/main/scala/chisel3/core/Aggregate.scala | 12 ++++++++---- src/main/scala/chisel3/util/Decoupled.scala | 10 +--------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 338479e..67a1651 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -263,6 +263,10 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) else self flatMap (e => List(e.toPrintable, PString(", "))) dropRight 1 PString("Vec(") + Printables(elts) + PString(")") } + + override def _onModuleClose: Unit = { + sample_element.setRef(this, 0) + } } /** A trait for [[Vec]]s containing common hardware generators for collection @@ -536,10 +540,10 @@ class Bundle extends Record { } override def cpy_lbls(that: this.type): Unit = { - // for ((name, elt) <- elements) { - // elt.cpy_lbls(that.elements(name).asInstanceOf[elt.type]) - // // that.elements(name).lbl_ = elt.lbl_ - // } + for ((name, elt) <- elements) { + elt.cpy_lbls(that.elements(name).asInstanceOf[elt.type]) + // that.elements(name).lbl_ = elt.lbl_ + } } /** Default "pretty-print" implementation diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 380baf8..54fe01e 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -27,18 +27,11 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: bits match { case bx: Record => for ((name, elt) <- elements.toIndexedSeq.reverse) { - println(s"elt: $name") - println(s"pprint elt: ${elt.getRef.pprint}") if(elt.lbl != null) { elt.lbl.conf match { case lx: HLevel => - if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) { - println("found name in bits") + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) - println(lx.toString) - println(s"pprint: ${lx.id.getRef.pprint}") - println(lx.name) - } case lx: VLabel => if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) @@ -56,7 +49,6 @@ abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: } } case _ => - println("bits is not a record") } } From 5b61470e0c6eacd7e7c79676607e3f1689b1f08a Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Mon, 29 May 2017 14:22:26 -0400 Subject: [PATCH 13/35] Support shadow fields. Label naming in Valids. Failed attempt at better label naming --- .../main/scala/chisel3/core/Aggregate.scala | 47 +++++++++++++++++-- .../main/scala/chisel3/internal/Builder.scala | 7 +++ .../scala/chisel3/internal/firrtl/IR.scala | 3 +- src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/main/scala/chisel3/util/Valid.scala | 47 ++++++++++++++++++- 5 files changed, 100 insertions(+), 6 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 67a1651..087be30 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -392,8 +392,7 @@ abstract class Record extends Aggregate { elements.toIndexedSeq.reverse.map(e => eltPort(e._2)).mkString("{", ", ", "}") } - private[chisel3] lazy val flatten = elements.toIndexedSeq.flatMap(_._2.flatten) - + def strTmp(s:String) = s contains "_T_" def argIsTemp(arg: Arg): Boolean = arg match { case ax: Ref => strTmp(ax.name) @@ -404,6 +403,46 @@ abstract class Record extends Aggregate { case ax: LitArg => false } + def slotsToNames(arg: Arg): Seq[String] = { + type Names = scala.collection.mutable.LinkedHashSet[String] + val names = new scala.collection.mutable.LinkedHashSet[String] + def slotsToSeq_(names: Names)(arg: Arg): Arg = arg match { + case ax: Slot => names += ax.name; slotsToSeq_(names)(ax.imm) + case ax: Node => slotsToSeq_(names)(ax.id.getRef) + case ax: Index => slotsToSeq_(names)(ax.imm) + case ax => ax + } + slotsToSeq_(names)(arg) + names.toSeq.reverse + } + + def namesToElt(names: Seq[String]): Data = { + var elt: Data = this + for(name <- names) elt match { + case ax: Record => + if(ax.elements contains name) elt = ax.elements(name) + case _ => + } + elt + } + + // def swapTmpWithId(arg: Arg, id:HasId): Arg = arg match { + // case ax: Ref => val r = (if(strTmp(ax.name)) Node(id) else ax); println(r.pprint); r + // case ax: Node => val r = (ax.id match { + // case axx: Ref if(strTmp(ax.name)) => Node(id) + // case _ => ax + // }); println(r.pprint); r + // // ax.id.setRef(swapTmpWithId(ax.id.getRef, id)); ax + // case ax: Slot => + // val r = Slot(swapTmpWithId(ax.imm, id).asInstanceOf[Node], ax.name); + // println(r.pprint); r + // case ax: Index => val r = Index(swapTmpWithId(ax.imm, id), ax.value); + // println(r.pprint); r + // case ax => val r = ax; println(r.pprint); r + // } + + private[chisel3] lazy val flatten = elements.toIndexedSeq.flatMap(_._2.flatten) + // NOTE: This sets up dependent references, it can be done before closing the Module private[chisel3] override def _onModuleClose: Unit = { // scalastyle:ignore method.name // Since Bundle names this via reflection, it is impossible for two elements to have the same @@ -486,11 +525,12 @@ class Bundle extends Record { final lazy val elements: ListMap[String, Data] = { val nameMap = LinkedHashMap[String, Data]() val seen = HashSet[Data]() + def isShadow(s:String) = s contains "shdw" for (m <- getPublicFields(classOf[Bundle])) { getBundleField(m) foreach { d => if (nameMap contains m.getName) { require(nameMap(m.getName) eq d) - } else if (!seen(d)) { + } else if (!seen(d) && !isShadow(m.getName)) { nameMap(m.getName) = d seen += d } @@ -499,6 +539,7 @@ class Bundle extends Record { ListMap(nameMap.toSeq sortWith { case ((an, a), (bn, b)) => (a._id > b._id) || ((a eq b) && (an > bn)) }: _*) } + /** Returns a field's contained user-defined Bundle element if it appears to * be one, otherwise returns None. */ diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index 023a4ea..e870405 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -66,6 +66,7 @@ trait InstanceId { def parentModName: String } + private[chisel3] trait HasId extends InstanceId { private[chisel3] def _onModuleClose: Unit = {} // scalastyle:ignore method.name private[chisel3] val _parent: Option[Module] = Builder.currentModule @@ -105,6 +106,12 @@ private[chisel3] trait HasId extends InstanceId { 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 setRef(parent: HasId, names: Seq[String]): Unit = { + // var newRef = Node(parent) + // for(name <- names) { + // newRef = Slot(Node(newRef), name) + // } + // } private[chisel3] def getRef: Arg = _ref.get private[chisel3] def refSet: Boolean = !_ref.isEmpty diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index e66e233..c890980 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -49,6 +49,7 @@ object PrimOp { val AsClockOp = PrimOp("asClock") } + abstract class Arg { def fullName(ctx: Component): String = name def name: String @@ -111,7 +112,7 @@ case class ModuleIO(mod: Module, name: String) extends Arg { } 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}" + s"${imm.fullName(ctx)}.${name}" def pprint = s"Slot(${imm.pprint}, ${name})" } case class Index(imm: Arg, value: Arg) extends Arg { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 54fe01e..29beefa 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -17,7 +17,7 @@ import chisel3.core.{HLevel, VLabel} * uses the flipped interface. Actual semantics of ready/valid are * enforced via use of concrete subclasses. */ -abstract class ReadyValidIO[+T <: Data](gen: T, rdyl: Label=UnknownLabel, vall: Label=UnknownLabel) extends Bundle +abstract class ReadyValidIO[+T <: Data](gen: T, val rdyl: Label=UnknownLabel, val vall: Label=UnknownLabel) extends Bundle { val ready = Input(Bool(), rdyl) val valid = Output(Bool(), vall) diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 2f0ea88..225ef43 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -9,13 +9,58 @@ import chisel3._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict +import chisel3.core.{HLevel, VLabel} +import chisel3.internal.firrtl.{Node} + /** An Bundle containing data and a signal determining if it is valid */ -class Valid[+T <: Data](gen: T, vall: Label=UnknownLabel) extends Bundle +class Valid[+T <: Data](gen: T, val vall: Label=UnknownLabel) extends Bundle { val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) def fire(dummy: Int = 0): Bool = valid override def cloneType: this.type = Valid(gen, vall).asInstanceOf[this.type] + override def _onModuleClose: Unit = { + super._onModuleClose + bits match { + case bx: Record => + if(valid.lbl != null) { + valid.lbl.conf match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) { + lx.id.setRef(bx, lx.id.getRef.name) + // println("valid hlvl ref: " + lx.id.getRef.pprint) + // println(s"this: ${this.getRef.pprint}") + // println(s"bx: ${bx.getRef.pprint}") + + // //lx.id.setRef(swapTmpWithId(lx.id.getRef, this)) + // val slots = slotsToNames(lx.id.getRef) + // val elt = bx.namesToElt(slots) + // println(s"slots: ${slots.toString}") + // println(s"elt: ${elt.toString}") + // println(s"eltId: ${elt.getRef.pprint}") + // lx.id.setRef(Node(elt)) + // lx.id.setRef(bx, lots) + // println (s"slots pretty: ${lx.id.getRef.pprint}") + // if(bx.elements contains lx.id.getRef.name) lx.id.setRef(bx, lx.id.getRef.name) + } + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx => + } + valid.lbl.integ match { + case lx: HLevel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx: VLabel => + if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) + lx.id.setRef(bx, lx.id.getRef.name) + case lx => + } + } + case _ => + } + } } /** Adds a valid protocol to any interface */ From 2fcfee700b1e6f07f4229381d5bed960527454ce Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Mon, 29 May 2017 16:53:10 -0400 Subject: [PATCH 14/35] Can label gen in Valid --- src/main/scala/chisel3/util/Valid.scala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 225ef43..40389ec 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -13,10 +13,13 @@ import chisel3.core.{HLevel, VLabel} import chisel3.internal.firrtl.{Node} /** An Bundle containing data and a signal determining if it is valid */ -class Valid[+T <: Data](gen: T, val vall: Label=UnknownLabel) extends Bundle +class Valid[+T <: Data](gen: T, val vall: Label=UnknownLabel, val genl: Label=UnknownLabel) extends Bundle { val valid = Output(Bool(), vall) - val bits = Output(gen.chiselCloneType) + val bits = genl match { + case UnknownLabel => Output(gen.chiselCloneType) + case _ => Output(gen.chiselCloneType, genl) + } def fire(dummy: Int = 0): Bool = valid override def cloneType: this.type = Valid(gen, vall).asInstanceOf[this.type] override def _onModuleClose: Unit = { @@ -65,7 +68,7 @@ class Valid[+T <: Data](gen: T, val vall: Label=UnknownLabel) extends Bundle /** Adds a valid protocol to any interface */ object Valid { - def apply[T <: Data](gen: T, lbl: Label=UnknownLabel): Valid[T] = new Valid(gen, lbl) + def apply[T <: Data](gen: T, vall: Label=UnknownLabel, genl: Label=UnknownLabel): Valid[T] = new Valid(gen, vall, genl) } /** A hardware module that delays data coming down the pipeline From 78cae7aa6545da63a5be544196f4d536cf706e0c Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 30 May 2017 14:39:58 -0400 Subject: [PATCH 15/35] Better errors for mysterious bad connections --- chiselFrontend/src/main/scala/chisel3/core/Data.scala | 4 ++-- chiselFrontend/src/main/scala/chisel3/core/Reg.scala | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 0fa18a2..6fb29cb 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -162,7 +162,7 @@ abstract class Data extends HasId with HasLabel{ } catch { case MonoConnect.MonoConnectException(message) => throwException( - s"Connection between sink ($this) and source ($that) failed @$message" + s"Connection between sink ($this) and source ($that) failed @$message si:${sourceInfo.makeMessage(x => x)}" ) } } else { @@ -178,7 +178,7 @@ abstract class Data extends HasId with HasLabel{ } catch { case BiConnect.BiConnectException(message) => throwException( - s"Connection between left ($this) and source ($that) failed @$message" + s"Connection between left ($this) and source ($that) failed @$message si:${sourceInfo.makeMessage(x => x)}" ) } } else { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala index 416c664..7df012b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Reg.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Reg.scala @@ -79,7 +79,13 @@ object Reg { pushCommand(DefRegInit(sourceInfo, x, clock, Node(x._parent.get.reset), init.ref, lbl)) } if (next != null) { - Binding.checkSynthesizable(next, s"'next' ($next)") + try { + Binding.checkSynthesizable(next, s"'next' ($next)") + } catch { + case (e: Exception) => + val inf = s"badness info: ${sourceInfo.makeMessage(x=>x)}\n" + throw new Exception(inf + e.getMessage()) + } x := next } x From 631ff0b11f1a70b75d6aa91868a4503da4c94ef1 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 1 Jun 2017 13:42:08 -0400 Subject: [PATCH 16/35] Explicit join labels --- chiselFrontend/src/main/scala/chisel3/core/Label.scala | 5 ++++- src/main/scala/chisel3/compatibility.scala | 2 ++ src/main/scala/chisel3/package.scala | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index c846271..3991068 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -82,5 +82,8 @@ object I { } // These are not parsed by sFIRRTL and are only used internally -// case class JoinLabel(l: Label, r: Label) extends Label +case class JoinLabelComp(l: LabelComp, r: LabelComp) extends LabelComp { + def name = s"${l.name} join ${r.name}" + def fullName(ctx: Component) = s"${l.fullName(ctx)} join ${r.fullName(ctx)}" +} // case class MeetLabel(l: Label, r: Label) extends Label diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index bca46da..e17d8b4 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -22,6 +22,7 @@ package object Chisel { // scalastyle:ignore package.object.name val FunLabel = chisel3.core.FunLabel val HLevel = chisel3.core.HLevel val VLabel = chisel3.core.VLabel + val JoinLabelComp = chisel3.core.JoinLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse @@ -39,6 +40,7 @@ package object Chisel { // scalastyle:ignore package.object.name val NODIR = chisel3.core.Direction.Unspecified object Flipped { def apply[T<:Data](target: T): T = chisel3.core.Flipped[T](target) + def apply[T<:Data](target: T, lbl: Label): T = chisel3.core.Flipped[T](target, lbl) } // TODO: Possibly move the AddDirectionToData class here? implicit class AddDirMethodToData[T<:Data](val target: T) extends AnyVal { diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index de6ae87..40dbcf4 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -31,6 +31,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val FunLabel = chisel3.core.FunLabel val HLevel = chisel3.core.HLevel val VLabel = chisel3.core.VLabel + val JoinLabelComp = chisel3.core.JoinLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse From 604318412ed947b46c76c608bc743c89ff096f6d Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Fri, 9 Jun 2017 15:35:14 -0400 Subject: [PATCH 17/35] Meet components for label joins --- chiselFrontend/src/main/scala/chisel3/core/Label.scala | 5 +++++ src/main/scala/chisel3/compatibility.scala | 1 + src/main/scala/chisel3/package.scala | 1 + 3 files changed, 7 insertions(+) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index 3991068..258ed2e 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -86,4 +86,9 @@ case class JoinLabelComp(l: LabelComp, r: LabelComp) extends LabelComp { def name = s"${l.name} join ${r.name}" def fullName(ctx: Component) = s"${l.fullName(ctx)} join ${r.fullName(ctx)}" } + +case class MeetLabelComp(l: LabelComp, r: LabelComp) extends LabelComp { + def name = s"${l.name} meet ${r.name}" + def fullName(ctx: Component) = s"${l.fullName(ctx)} meet ${r.fullName(ctx)}" +} // case class MeetLabel(l: Label, r: Label) extends Label diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index e17d8b4..8f58bf1 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -23,6 +23,7 @@ package object Chisel { // scalastyle:ignore package.object.name val HLevel = chisel3.core.HLevel val VLabel = chisel3.core.VLabel val JoinLabelComp = chisel3.core.JoinLabelComp + val MeetLabelComp = chisel3.core.MeetLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 40dbcf4..2d50f32 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -32,6 +32,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val HLevel = chisel3.core.HLevel val VLabel = chisel3.core.VLabel val JoinLabelComp = chisel3.core.JoinLabelComp + val MeetLabelComp = chisel3.core.MeetLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse From 4df7ccafb881e574dd932b39abd68dbafdc3a11e Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Mon, 19 Jun 2017 14:19:19 -0500 Subject: [PATCH 18/35] Fix NPE for naming --- .../src/main/scala/chisel3/core/Aggregate.scala | 8 ++++---- src/main/scala/chisel3/util/Decoupled.scala | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 087be30..8f7fab9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -457,19 +457,19 @@ abstract class Record extends Aggregate { for ((name, elt) <- elements.toIndexedSeq.reverse) { if(elt.lbl != null) { elt.lbl.conf match { - case lx: HLevel => + case lx: HLevel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel => + case lx: VLabel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) case lx => } elt.lbl.integ match { - case lx: HLevel => + case lx: HLevel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel => + case lx: VLabel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) case lx => diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 29beefa..0b01c31 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -29,19 +29,19 @@ abstract class ReadyValidIO[+T <: Data](gen: T, val rdyl: Label=UnknownLabel, va for ((name, elt) <- elements.toIndexedSeq.reverse) { if(elt.lbl != null) { elt.lbl.conf match { - case lx: HLevel => + case lx: HLevel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) - case lx: VLabel => + case lx: VLabel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) case lx => } elt.lbl.integ match { - case lx: HLevel => + case lx: HLevel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) - case lx: VLabel => + case lx: VLabel if(lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) lx.id.setRef(bx, lx.id.getRef.name) case lx => From 6af9381bde34c19651b1a1ee2ba7d1459d02d34e Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 28 Jun 2017 18:30:08 -0400 Subject: [PATCH 19/35] Another NPE for naming --- .../src/main/scala/chisel3/core/Aggregate.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 8f7fab9..7034da1 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -457,19 +457,19 @@ abstract class Record extends Aggregate { for ((name, elt) <- elements.toIndexedSeq.reverse) { if(elt.lbl != null) { elt.lbl.conf match { - case lx: HLevel if(lx.id.refSet) => + case lx: HLevel if(lx.id != null && lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel if(lx.id.refSet) => + case lx: VLabel if(lx.id != null && lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) case lx => } elt.lbl.integ match { - case lx: HLevel if(lx.id.refSet) => + case lx: HLevel if(lx.id != null && lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel if(lx.id.refSet) => + case lx: VLabel if(lx.id != null && lx.id.refSet) => if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) lx.id.setRef(this, lx.id.getRef.name) case lx => From 442f7ffd6cffa28187466c9538d52cdf64a6eee2 Mon Sep 17 00:00:00 2001 From: Mark Zhao Date: Fri, 7 Jul 2017 16:12:53 -0400 Subject: [PATCH 20/35] Pipes (at least the end of the pipe) now takes labels --- src/main/scala/chisel3/util/Valid.scala | 36 +++++++++++++------------ 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 40389ec..bb907af 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -1,7 +1,7 @@ // See LICENSE for license details. /** Wrappers for valid interfaces and associated circuit generators using them. - */ + */ package chisel3.util @@ -61,7 +61,7 @@ class Valid[+T <: Data](gen: T, val vall: Label=UnknownLabel, val genl: Label=Un case lx => } } - case _ => + case _ => } } } @@ -72,37 +72,39 @@ object Valid { } /** A hardware module that delays data coming down the pipeline - by the number of cycles set by the latency parameter. Functionality - is similar to ShiftRegister but this exposes a Pipe interface. + by the number of cycles set by the latency parameter. Functionality + is similar to ShiftRegister but this exposes a Pipe interface. - Example usage: - val pipe = new Pipe(UInt()) - pipe.io.enq <> produce.io.out - consumer.io.in <> pipe.io.deq - */ + Example usage: + val pipe = new Pipe(UInt()) + pipe.io.enq <> produce.io.out + consumer.io.in <> pipe.io.deq + */ object Pipe { - def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): Valid[T] = { + def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int, pvall: Label, pgenl: Label): Valid[T] = { if (latency == 0) { - val out = Wire(Valid(enqBits)) + val out = Wire(Valid(enqBits, vall=pvall, genl=pgenl)) out.valid <> enqValid out.bits <> enqBits out } else { val v = Reg(Bool(), next=enqValid, init=false.B) val b = RegEnable(enqBits, enqValid) - apply(v, b, latency-1) + apply(v, b, latency-1, pvall, pgenl) } } - def apply[T <: Data](enqValid: Bool, enqBits: T): Valid[T] = apply(enqValid, enqBits, 1) - def apply[T <: Data](enq: Valid[T], latency: Int = 1): Valid[T] = apply(enq.valid, enq.bits, latency) + def apply[T <: Data](enqValid: Bool, enqBits: T): Valid[T] = apply(enqValid, enqBits, 1, UnknownLabel, UnknownLabel) + def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): Valid[T] = apply(enqValid, enqBits, latency, UnknownLabel, UnknownLabel) + def apply[T <: Data](enq: Valid[T], latency: Int = 1, pvall: Label = UnknownLabel, pgenl: Label=UnknownLabel): Valid[T] = apply(enq.valid, enq.bits, latency, pvall, pgenl) + //def apply[T <: Data](enq: Valid[T], latency: Int= 1, pvall: Label, pgenl: Label): Valid[T] = apply(enq.valid, enq.bits, latency, pvall, pgenl) } -class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module +class Pipe[T <: Data](gen: T, latency: Int = 1, pvall: Label=UnknownLabel, pgenl: Label=UnknownLabel) extends Module { class PipeIO extends Bundle { - val enq = Input(Valid(gen)) - val deq = Output(Valid(gen)) + val enq = Input(Valid(gen, pvall, pgenl)) + val deq = Output(Valid(gen, pvall, pgenl)) } val io = IO(new PipeIO) From ed6046e27001557ac12a3e6862020852e4198a7c Mon Sep 17 00:00:00 2001 From: Mark Zhao Date: Mon, 17 Jul 2017 14:33:40 -0400 Subject: [PATCH 21/35] Labeled Queues, Arbiters --- src/main/scala/chisel3/util/Arbiter.scala | 6 ++-- src/main/scala/chisel3/util/Decoupled.scala | 32 ++++++++++++--------- 2 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 3486aa0..de51fba 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -8,6 +8,8 @@ package chisel3.util import chisel3._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict +import labelutil._ +import labelutil.LU._ /** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs * (selects) at most one. @@ -125,8 +127,8 @@ class RRArbiter[T <: Data](gen:T, n: Int, inl: Label, outl: Label) * consumer.io.in <> arb.io.out * }}} */ -class Arbiter[T <: Data](gen: T, n: Int) extends Module { - val io = IO(new ArbiterIO(gen, n)) +class Arbiter[T <: Data](gen: T, n: Int, inl: Label, outl: Label) extends Module { + val io = IO(new ArbiterIO(gen, n, inl, outl)) io.chosen := (n-1).asUInt io.out.bits := io.in(n-1).bits diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 0b01c31..fb892a2 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -167,25 +167,27 @@ object Irrevocable } object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Decoupled(gen) + def apply[T<:Data](gen: T, rdyl: Label = UnknownLabel, vall: Label=UnknownLabel): DecoupledIO[T] = Decoupled(gen, rdyl, vall) } object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen)) + def apply[T<:Data](gen: T, rdyl: Label = UnknownLabel, vall: Label=UnknownLabel): DecoupledIO[T] = Flipped(Decoupled(gen, rdyl, vall)) } /** An I/O Bundle for Queues * @param gen The type of data to queue * @param entries The max number of entries in the queue */ -class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle +class QueueIO[T <: Data](gen: T, entries: Int, rdyl: Label = UnknownLabel, + vall: Label = UnknownLabel) extends Bundle { /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ - val enq = DeqIO(gen) + val enq = DeqIO(gen, rdyl, vall) /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ - val deq = EnqIO(gen) + val deq = EnqIO(gen, rdyl, vall) /** The current amount of data in the queue */ - val count = Output(UInt(log2Up(entries + 1).W)) + //For now label the count the same level as the rdy/val + val count = Output(UInt(log2Up(entries + 1).W), lbl=rdyl) - override def cloneType = new QueueIO(gen, entries).asInstanceOf[this.type] + override def cloneType = new QueueIO(gen, entries, rdyl, vall).asInstanceOf[this.type] } /** A hardware module implementing a Queue @@ -206,12 +208,14 @@ class Queue[T <: Data](gen: T, val entries: Int, pipe: Boolean = false, flow: Boolean = false, - override_reset: Option[Bool] = None) + override_reset: Option[Bool] = None, + rdyl: Label = UnknownLabel, + vall: Label = UnknownLabel) extends Module(override_reset=override_reset) { - def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool) = - this(gen, entries, pipe, flow, Some(_reset)) + def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool, rdyl: Label, vall: Label) = + this(gen, entries, pipe, flow, Some(_reset), rdyl, vall) - val io = IO(new QueueIO(gen, entries)) + val io = IO(new QueueIO(gen, entries, rdyl, vall)) private val ram = Mem(entries, gen) private val enq_ptr = Counter(entries) @@ -282,8 +286,10 @@ object Queue enq: ReadyValidIO[T], entries: Int = 2, pipe: Boolean = false, - flow: Boolean = false): DecoupledIO[T] = { - val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow)) + flow: Boolean = false, + rdyl: Label = UnknownLabel, + vall: Label = UnknownLabel): DecoupledIO[T] = { + val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow, rdyl = rdyl, vall = vall)) q.io.enq.valid := enq.valid // not using <> so that override is allowed q.io.enq.bits := enq.bits enq.ready := q.io.enq.ready From 514fef0208e138d6e7abb338ae486f8fc2f3cb0a Mon Sep 17 00:00:00 2001 From: Mark Zhao Date: Mon, 17 Jul 2017 14:53:23 -0400 Subject: [PATCH 22/35] Fixed import bug in Arbiter.scala --- src/main/scala/chisel3/util/Arbiter.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index de51fba..d1f1ed5 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -8,8 +8,6 @@ package chisel3.util import chisel3._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict -import labelutil._ -import labelutil.LU._ /** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs * (selects) at most one. From 1c68cbeff3b6f872424ae106da9e25576514da9d Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 18 Jul 2017 11:31:56 -0400 Subject: [PATCH 23/35] Fix naming of dependands in cloned records. --- .../main/scala/chisel3/core/Aggregate.scala | 92 +++++++++---------- src/main/scala/chisel3/util/Arbiter.scala | 2 + src/main/scala/chisel3/util/Decoupled.scala | 26 +----- 3 files changed, 47 insertions(+), 73 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 7034da1..1d0456b 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -354,7 +354,7 @@ trait VecLike[T <: Data] extends collection.IndexedSeq[T] with HasId { * Record should only be extended by libraries and fairly sophisticated generators. * RTL writers should use [[Bundle]]. */ -abstract class Record extends Aggregate { +abstract class Record extends Aggregate with BitsLevelNamer { /** The collection of [[Data]] * @@ -392,17 +392,6 @@ abstract class Record extends Aggregate { elements.toIndexedSeq.reverse.map(e => eltPort(e._2)).mkString("{", ", ", "}") } - - def strTmp(s:String) = s contains "_T_" - def argIsTemp(arg: Arg): Boolean = arg match { - case ax: Ref => strTmp(ax.name) - case ax: ModuleIO => strTmp(ax.name) || strTmp(ax.mod.name) - case ax: Slot => !ax.imm.id.refSet || argIsTemp(ax.imm.id.getRef) || strTmp(ax.name) - case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) - case ax: Node => !ax.id.refSet || strTmp(ax.name) - case ax: LitArg => false - } - def slotsToNames(arg: Arg): Seq[String] = { type Names = scala.collection.mutable.LinkedHashSet[String] val names = new scala.collection.mutable.LinkedHashSet[String] @@ -426,21 +415,6 @@ abstract class Record extends Aggregate { elt } - // def swapTmpWithId(arg: Arg, id:HasId): Arg = arg match { - // case ax: Ref => val r = (if(strTmp(ax.name)) Node(id) else ax); println(r.pprint); r - // case ax: Node => val r = (ax.id match { - // case axx: Ref if(strTmp(ax.name)) => Node(id) - // case _ => ax - // }); println(r.pprint); r - // // ax.id.setRef(swapTmpWithId(ax.id.getRef, id)); ax - // case ax: Slot => - // val r = Slot(swapTmpWithId(ax.imm, id).asInstanceOf[Node], ax.name); - // println(r.pprint); r - // case ax: Index => val r = Index(swapTmpWithId(ax.imm, id), ax.value); - // println(r.pprint); r - // case ax => val r = ax; println(r.pprint); r - // } - private[chisel3] lazy val flatten = elements.toIndexedSeq.flatMap(_._2.flatten) // NOTE: This sets up dependent references, it can be done before closing the Module @@ -454,29 +428,6 @@ abstract class Record extends Aggregate { elt.setRef(this, _namespace.name(name)) } - for ((name, elt) <- elements.toIndexedSeq.reverse) { - if(elt.lbl != null) { - elt.lbl.conf match { - case lx: HLevel if(lx.id != null && lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) - lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel if(lx.id != null && lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) - lx.id.setRef(this, lx.id.getRef.name) - case lx => - } - elt.lbl.integ match { - case lx: HLevel if(lx.id != null && lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) - lx.id.setRef(this, lx.id.getRef.name) - case lx: VLabel if(lx.id != null && lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (elements contains lx.id.getRef.name)) - lx.id.setRef(this, lx.id.getRef.name) - case lx => - } - } - } - } private[chisel3] final def allElements: Seq[Element] = elements.toIndexedSeq.flatMap(_._2.allElements) @@ -601,3 +552,44 @@ private[core] object Bundle { "widthOption", "signalName", "signalPathName", "signalParent", "signalComponent") } + +trait BitsLevelNamer { + + def strTmp(s:String) = s contains "_T_" + def argIsTemp(arg: Arg): Boolean = arg match { + case ax: Ref => strTmp(ax.name) + case ax: ModuleIO => strTmp(ax.name) || strTmp(ax.mod.name) + case ax: Slot => !ax.imm.id.refSet || argIsTemp(ax.imm.id.getRef) || strTmp(ax.name) + case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) + case ax: Node => !ax.id.refSet || strTmp(ax.name) + case ax: LitArg => false + } + + + def nameBitsInLevels(namedRecord: Record, outerRecord: Record): Unit = { + val nameElts = namedRecord.elements.toIndexedSeq.reverse ++ outerRecord.elements.toIndexedSeq.reverse + for ((name, elt) <- nameElts) { + if(elt.lbl != null) { + elt.lbl.conf match { + case lx: HLevel if(lx.id.refSet) => + if(argIsTemp(lx.id.getRef) && (namedRecord.elements contains lx.id.getRef.name)) + lx.id.setRef(namedRecord, lx.id.getRef.name) + case lx: VLabel if(lx.id.refSet) => + if(argIsTemp(lx.id.getRef) && (namedRecord.elements contains lx.id.getRef.name)) + lx.id.setRef(namedRecord, lx.id.getRef.name) + case lx => + } + elt.lbl.integ match { + case lx: HLevel if(lx.id.refSet) => + if(argIsTemp(lx.id.getRef) && (namedRecord.elements contains lx.id.getRef.name)) + lx.id.setRef(namedRecord, lx.id.getRef.name) + case lx: VLabel if(lx.id.refSet) => + if(argIsTemp(lx.id.getRef) && (namedRecord.elements contains lx.id.getRef.name)) + lx.id.setRef(namedRecord, lx.id.getRef.name) + case lx => + } + } + } + } +} + diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index d1f1ed5..cc4977c 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -128,6 +128,8 @@ class RRArbiter[T <: Data](gen:T, n: Int, inl: Label, outl: Label) class Arbiter[T <: Data](gen: T, n: Int, inl: Label, outl: Label) extends Module { val io = IO(new ArbiterIO(gen, n, inl, outl)) + def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) + io.chosen := (n-1).asUInt io.out.bits := io.in(n-1).bits for (i <- n-2 to 0 by -1) { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index fb892a2..f8c9f3b 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -22,35 +22,14 @@ abstract class ReadyValidIO[+T <: Data](gen: T, val rdyl: Label=UnknownLabel, va val ready = Input(Bool(), rdyl) val valid = Output(Bool(), vall) val bits = Output(gen.chiselCloneType) + override def _onModuleClose: Unit = { super._onModuleClose bits match { case bx: Record => - for ((name, elt) <- elements.toIndexedSeq.reverse) { - if(elt.lbl != null) { - elt.lbl.conf match { - case lx: HLevel if(lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) - lx.id.setRef(bx, lx.id.getRef.name) - case lx: VLabel if(lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) - lx.id.setRef(bx, lx.id.getRef.name) - case lx => - } - elt.lbl.integ match { - case lx: HLevel if(lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) - lx.id.setRef(bx, lx.id.getRef.name) - case lx: VLabel if(lx.id.refSet) => - if(argIsTemp(lx.id.getRef) && (bx.elements contains lx.id.getRef.name)) - lx.id.setRef(bx, lx.id.getRef.name) - case lx => - } - } - } + nameBitsInLevels(bx, this) case _ => } - } } @@ -228,6 +207,7 @@ extends Module(override_reset=override_reset) { private val do_enq = Wire(init=io.enq.fire()) private val do_deq = Wire(init=io.deq.fire()) + when (do_enq) { ram(enq_ptr.value) := io.enq.bits enq_ptr.inc() From 2be282c1e801e50c907d3c4b0d1aae680bc46870 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 19 Jul 2017 13:52:05 -0400 Subject: [PATCH 24/35] Deep copy labels --- .../main/scala/chisel3/core/Aggregate.scala | 31 ++++++++++++++++++- src/main/scala/chisel3/util/Decoupled.scala | 8 ++--- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 1d0456b..5f29dd9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -500,6 +500,33 @@ class Bundle extends Record { case _ => None } + def elementsRec = { + var eltSets = new ListMap[String, Data] + eltSets ++= elements + elements.map { _._2 } match { + case elt: Record => eltSets ++= elt.elements + case _ => + } + eltSets + } + + def renamedDepComp(labelComp: LabelComp, orig: Bundle, clone: Bundle): LabelComp = labelComp match { + case lx: HLevel => + val oldElt = orig.elementsRec.find( _._2 == lx.id ) + if( !oldElt.isEmpty ) { + val name = oldElt.get._1 + HLevel(clone.elements(name)) + } else { + lx + } + case _ => labelComp + } + + def renameLabelsOfClone(clone: this.type): Unit = + for((name, elt) <- clone.elements) + elt.lbl_ = Label(renamedDepComp(elt.lbl_.conf, this, clone), + renamedDepComp(elt.lbl_.integ, this, clone)) + override def cloneType : this.type = { // If the user did not provide a cloneType method, try invoking one of // the following constructors, not all of which necessarily exist: @@ -508,7 +535,7 @@ class Bundle extends Record { // - A one-parameter constructor for a nested Bundle, with the enclosing // parent Module as the argument val constructor = this.getClass.getConstructors.head - try { + val dataClone: this.type = try { val args = Seq.fill(constructor.getParameterTypes.size)(null) val ret = constructor.newInstance(args:_*).asInstanceOf[this.type] cpy_lbls(ret) @@ -529,6 +556,8 @@ class Bundle extends Record { Builder.exception(s"Parameterized Bundle ${this.getClass} needs cloneType method") this } + renameLabelsOfClone(dataClone) + dataClone } override def cpy_lbls(that: this.type): Unit = { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index f8c9f3b..55e4d5b 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -85,8 +85,9 @@ class DecoupledIO[+T <: Data](gen: T, rdyl: Label, vall: Label) extends ReadyVal { override def cloneType: this.type = { val ret = new DecoupledIO(gen, rdyl, vall).asInstanceOf[this.type] - cpy_lbls(ret) - bits.cpy_lbls(ret.bits) + renameLabelsOfClone(ret) + // cpy_lbls(ret) + // bits.cpy_lbls(ret.bits) ret } def this(gen: T) = this(gen, UnknownLabel, UnknownLabel) @@ -110,9 +111,6 @@ object Decoupled irr.ready := d.ready d } -// override def cloneType: this.type = { -// DeqIO(gen).asInstanceOf[this.type] -// } } /** A concrete subclass of ReadyValidIO that promises to not change From 3e02f6f5f6db45912002a44ea2777d6cf8a37850 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 19 Jul 2017 14:27:57 -0400 Subject: [PATCH 25/35] Fix cloning by making HLevels updatable singletones that hold mutable IDs --- .../main/scala/chisel3/core/Aggregate.scala | 5 ++-- .../src/main/scala/chisel3/core/Label.scala | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 5f29dd9..2a4b082 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -514,8 +514,9 @@ class Bundle extends Record { case lx: HLevel => val oldElt = orig.elementsRec.find( _._2 == lx.id ) if( !oldElt.isEmpty ) { - val name = oldElt.get._1 - HLevel(clone.elements(name)) + val newElt = clone.elementsRec(oldElt.get._1) + HLevel.update(newElt, lx) + lx } else { lx } diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index 258ed2e..e9bd609 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -53,10 +53,37 @@ object FunLabel{ def apply(fname: String, ids: HasId*) = new FunLabel(fname, ids.toList) } +/* case class HLevel(id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]H" def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" } +*/ + +class HLevel private(var id: HasId) extends LabelComp { + def name = s"[[${id.getRef.name}]]H" + def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" + override def equals(that: Any) = that match { + case lx: HLevel => lx.id == this.id + case _ => false + } + override def hashCode = id.hashCode +} + +object HLevel { + private val hlevels = new scala.collection.mutable.HashMap[HasId, HLevel] + def apply(id: HasId): HLevel = { + if(!(hlevels contains id)) + hlevels(id) = new HLevel(id) + hlevels(id) + } + def unapply(hl: HLevel) = Some(hl.id) + def update(id: HasId, hl: HLevel) { + hlevels -= hl.id + hl.id = id + hlevels(id) = hl + } +} case class VLabel(id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]V" From 68177a3efc8867047586135fc74405ed6ec36bc7 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Fri, 21 Jul 2017 16:35:05 -0400 Subject: [PATCH 26/35] This naming fix is 10% fixier than the last --- .../main/scala/chisel3/core/Aggregate.scala | 18 ++---------------- .../src/main/scala/chisel3/core/Label.scala | 13 +++++++++---- 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 2a4b082..6f01a20 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -510,23 +510,9 @@ class Bundle extends Record { eltSets } - def renamedDepComp(labelComp: LabelComp, orig: Bundle, clone: Bundle): LabelComp = labelComp match { - case lx: HLevel => - val oldElt = orig.elementsRec.find( _._2 == lx.id ) - if( !oldElt.isEmpty ) { - val newElt = clone.elementsRec(oldElt.get._1) - HLevel.update(newElt, lx) - lx - } else { - lx - } - case _ => labelComp - } - def renameLabelsOfClone(clone: this.type): Unit = - for((name, elt) <- clone.elements) - elt.lbl_ = Label(renamedDepComp(elt.lbl_.conf, this, clone), - renamedDepComp(elt.lbl_.integ, this, clone)) + for( (name, elt) <- elements ) + HLevel.replace(elt, clone.elements.find( _._1 == name).get._2) override def cloneType : this.type = { // If the user did not provide a cloneType method, try invoking one of diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index e9bd609..5a26d59 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -63,11 +63,13 @@ case class HLevel(id: HasId) extends LabelComp { class HLevel private(var id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]H" def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]H" + /* override def equals(that: Any) = that match { case lx: HLevel => lx.id == this.id case _ => false } override def hashCode = id.hashCode + */ } object HLevel { @@ -78,10 +80,13 @@ object HLevel { hlevels(id) } def unapply(hl: HLevel) = Some(hl.id) - def update(id: HasId, hl: HLevel) { - hlevels -= hl.id - hl.id = id - hlevels(id) = hl + private[chisel3] def replace(oldId: HasId, newId: HasId) { + if(hlevels contains oldId) { + val oldHLevel = hlevels(oldId) + oldHLevel.id = newId + hlevels -= oldId + hlevels(newId) = oldHLevel + } } } From 2a35f631b24bbe75f147ac6089127f3aa9b70911 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Fri, 21 Jul 2017 19:59:34 -0400 Subject: [PATCH 27/35] Labeled arbiter interface needs to change because of how labels and object pointers work now --- src/main/scala/chisel3/util/Arbiter.scala | 36 +++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index cc4977c..20d9c54 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -15,11 +15,11 @@ import chisel3.core.ExplicitCompileOptions.NotStrict * @param gen data type * @param n number of inputs */ -class ArbiterIO[T <: Data](gen: T, n: Int, inl: Label, outl: Label) extends Bundle { +class ArbiterIO[T <: Data](gen: T, out_gen: T, n: Int, inl: Label, outl: Label) extends Bundle { val in = Flipped(Vec(n, Decoupled(gen, inl, inl))) - val out = Decoupled(gen, outl, outl) + val out = Decoupled(out_gen, outl, outl) val chosen = Output(UInt(log2Up(n).W), outl) - def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) + def this(gen: T, n: Int) = this(gen, gen, n, UnknownLabel, UnknownLabel) } /** Arbiter Control determining which producer has access @@ -32,11 +32,11 @@ private object ArbiterCtrl { } } -abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, +abstract class LockingArbiterLike[T <: Data](gen: T, out_gen: T, n: Int, count: Int, needsLock: Option[T => Bool], inl: Label, outl: Label) extends Module { protected def grant: Seq[Bool] protected def choice: UInt - val io = IO(new ArbiterIO(gen, n, inl, outl)) + val io = IO(new ArbiterIO(gen, out_gen, n, inl, outl)) io.chosen := choice io.out.valid := io.in(io.chosen).valid @@ -62,12 +62,12 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, } def this(gen: T, n: Int, count: Int, needsLock: Option[T=>Bool]) - = this(gen, n, count, needsLock, UnknownLabel, UnknownLabel) + = this(gen, gen, n, count, needsLock, UnknownLabel, UnknownLabel) } -class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, +class LockingRRArbiter[T <: Data](gen: T, out_gen: T, n: Int, count: Int, inl: Label, outl: Label, needsLock: Option[T => Bool]) - extends LockingArbiterLike[T](gen, n, count, needsLock, inl, outl) { + extends LockingArbiterLike[T](gen, out_gen, n, count, needsLock, inl, outl) { private lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) private lazy val grantMask = (0 until n).map(_.asUInt > lastGrant) private lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } @@ -84,12 +84,12 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, when (validMask(i)) { choice := i.asUInt } def this(gen: T, n: Int, count: Int, needsLock: Option[T => Bool ] = None) = - this(gen, n, count, UnknownLabel, UnknownLabel, needsLock) + this(gen, gen, n, count, UnknownLabel, UnknownLabel, needsLock) } -class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, +class LockingArbiter[T <: Data](gen: T, out_gen: T, n: Int, count: Int, inl: Label, outl: Label, needsLock: Option[T => Bool]) - extends LockingArbiterLike[T](gen, n, count, needsLock, inl, outl) { + extends LockingArbiterLike[T](gen, out_gen, n, count, needsLock, inl, outl) { protected def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) override protected lazy val choice = Wire(init=(n-1).asUInt) @@ -97,7 +97,7 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, when (io.in(i).valid) { choice := i.asUInt } def this(gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) = - this(gen, n, count, UnknownLabel, UnknownLabel, needsLock) + this(gen, gen, n, count, UnknownLabel, UnknownLabel, needsLock) } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -110,9 +110,9 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, * consumer.io.in <> arb.io.out * }}} */ -class RRArbiter[T <: Data](gen:T, n: Int, inl: Label, outl: Label) - extends LockingRRArbiter[T](gen, n, 1, inl, outl, None) { - def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) +class RRArbiter[T <: Data](gen:T, out_gen: T, n: Int, inl: Label, outl: Label) + extends LockingRRArbiter[T](gen, out_gen, n, 1, inl, outl, None) { + def this(gen: T, n: Int) = this(gen, gen, n, UnknownLabel, UnknownLabel) } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -125,10 +125,10 @@ class RRArbiter[T <: Data](gen:T, n: Int, inl: Label, outl: Label) * consumer.io.in <> arb.io.out * }}} */ -class Arbiter[T <: Data](gen: T, n: Int, inl: Label, outl: Label) extends Module { - val io = IO(new ArbiterIO(gen, n, inl, outl)) +class Arbiter[T <: Data](gen: T, out_gen: T, n: Int, inl: Label, outl: Label) extends Module { + val io = IO(new ArbiterIO(gen, out_gen, n, inl, outl)) - def this(gen: T, n: Int) = this(gen, n, UnknownLabel, UnknownLabel) + def this(gen: T, n: Int) = this(gen, gen, n, UnknownLabel, UnknownLabel) io.chosen := (n-1).asUInt io.out.bits := io.in(n-1).bits From 59d1eb98fe44b8903673d1022fff87347fc1d71e Mon Sep 17 00:00:00 2001 From: Mark Zhao Date: Sat, 22 Jul 2017 13:22:31 -0400 Subject: [PATCH 28/35] Output label for decoupled Queues --- src/main/scala/chisel3/util/Decoupled.scala | 56 ++++++++++++++------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 55e4d5b..06e04ac 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -152,19 +152,24 @@ object DeqIO { /** An I/O Bundle for Queues * @param gen The type of data to queue - * @param entries The max number of entries in the queue */ -class QueueIO[T <: Data](gen: T, entries: Int, rdyl: Label = UnknownLabel, - vall: Label = UnknownLabel) extends Bundle + * @param out_gen The type of the output of the queue + * @param entries The max number of entries in the queue + * @param inl The label of the queue's input + * @param outl The label of the queue's output*/ +class QueueIO[T <: Data](gen: T, entries: Int, inl: Label = UnknownLabel, + outl: Label = UnknownLabel, out_gen: Option[T] = None) extends Bundle { + //For some reason, the Enq and Deq names are flipped.... /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ - val enq = DeqIO(gen, rdyl, vall) + val enq = DeqIO(gen, inl, inl) /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ - val deq = EnqIO(gen, rdyl, vall) + val out_gen_ = out_gen.getOrElse(gen) + val deq = EnqIO(out_gen_, outl, outl) /** The current amount of data in the queue */ - //For now label the count the same level as the rdy/val - val count = Output(UInt(log2Up(entries + 1).W), lbl=rdyl) + //For now label the count the same level as the output's level + val count = Output(UInt(log2Up(entries + 1).W), lbl=outl) - override def cloneType = new QueueIO(gen, entries, rdyl, vall).asInstanceOf[this.type] + override def cloneType = new QueueIO(gen, entries, inl, outl, out_gen).asInstanceOf[this.type] } /** A hardware module implementing a Queue @@ -174,6 +179,8 @@ class QueueIO[T <: Data](gen: T, entries: Int, rdyl: Label = UnknownLabel, * combinationally coupled. * @param flow True if the inputs can be consumed on the same cycle (the inputs "flow" through the queue immediately). * The ''valid'' signals are coupled. + * @param inl The label of the queue's input + * @param outl The label of the queue's output * * @example {{{ * val q = new Queue(UInt(), 16) @@ -186,13 +193,13 @@ class Queue[T <: Data](gen: T, pipe: Boolean = false, flow: Boolean = false, override_reset: Option[Bool] = None, - rdyl: Label = UnknownLabel, - vall: Label = UnknownLabel) + inl: Label = UnknownLabel, + outl: Label = UnknownLabel, + out_gen: Option[T] = None) extends Module(override_reset=override_reset) { - def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool, rdyl: Label, vall: Label) = - this(gen, entries, pipe, flow, Some(_reset), rdyl, vall) - - val io = IO(new QueueIO(gen, entries, rdyl, vall)) + def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool, inl: Label, outl: Label, out_gen: T) = this(gen, entries, pipe, flow, Some(_reset), inl, outl, Some(out_gen)) + + val io = IO(new QueueIO(gen, entries, inl, outl, out_gen)) private val ram = Mem(entries, gen) private val enq_ptr = Counter(entries) @@ -265,9 +272,12 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false, - rdyl: Label = UnknownLabel, - vall: Label = UnknownLabel): DecoupledIO[T] = { - val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow, rdyl = rdyl, vall = vall)) + inl: Label = UnknownLabel, + outl: Label = UnknownLabel, + deq: Option[ReadyValidIO[T]] = None): DecoupledIO[T] = { + + val deq_ = deq.getOrElse(enq) + val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow, inl = inl, outl = outl, out_gen = Some(deq_.bits.cloneType))) q.io.enq.valid := enq.valid // not using <> so that override is allowed q.io.enq.bits := enq.bits enq.ready := q.io.enq.ready @@ -284,6 +294,7 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): IrrevocableIO[T] = { + //This module isn't really used in labeling yet, so just use enq type as the deq. val deq = apply(enq, entries, pipe, flow) val irr = Wire(new IrrevocableIO(deq.bits)) irr.bits := deq.bits @@ -292,3 +303,14 @@ object Queue irr } } + +/** + * Factory for constructing a labeled queue that has an deq type specified + * */ +//object LabeledQueue +//{ +// /** Create a queue and supply a DecoupledIO containing the product. */ +// def apply[T <: Data]( +// enq: ReadyValidIO[T], +// deq: ReadyValidIO[T], +// From 93ac1b3fad99a993d8faeb581f4eff259455e9f8 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 10 Aug 2017 15:41:25 -0400 Subject: [PATCH 29/35] Mems are fully-named. Remove incorrect renaming. --- chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala | 5 +++++ chiselFrontend/src/main/scala/chisel3/core/Data.scala | 4 ++++ chiselFrontend/src/main/scala/chisel3/core/Module.scala | 7 +++++++ src/main/scala/chisel3/util/Decoupled.scala | 3 +-- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 6f01a20..049e90a 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -510,9 +510,14 @@ class Bundle extends Record { eltSets } + /* def renameLabelsOfClone(clone: this.type): Unit = for( (name, elt) <- elements ) HLevel.replace(elt, clone.elements.find( _._1 == name).get._2) + */ + + def renameLabelsOfClone(clone: this.type) : Unit = { + } override def cloneType : this.type = { // If the user did not provide a cloneType method, try invoking one of diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 6fb29cb..1fbb70a 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -151,6 +151,10 @@ abstract class Data extends HasId with HasLabel{ protected[chisel3] var lbl_ : Label = UnknownLabel def lbl = lbl_ + def setLabel(lb: Label): Unit = { + lbl_ = lb + } + private[core] def badConnect(that: Data)(implicit sourceInfo: SourceInfo): Unit = throwException(s"cannot connect ${this} and ${that}") private[chisel3] def connect(that: Data)(implicit sourceInfo: SourceInfo, connectCompileOptions: CompileOptions): Unit = { diff --git a/chiselFrontend/src/main/scala/chisel3/core/Module.scala b/chiselFrontend/src/main/scala/chisel3/core/Module.scala index e396edc..50a6a77 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Module.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Module.scala @@ -220,6 +220,13 @@ extends HasId { // All suggestions are in, force names to every node. _ids.foreach(_.forceName(default="_T", _namespace)) + + _commands.foreach { _ match { + case cmd: DefMemory => + cmd.t.setRef(cmd.id.getRef) + case _ => + }} + _ids.foreach(_._onModuleClose) this } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 06e04ac..b09d2ee 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -163,8 +163,7 @@ class QueueIO[T <: Data](gen: T, entries: Int, inl: Label = UnknownLabel, /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ val enq = DeqIO(gen, inl, inl) /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ - val out_gen_ = out_gen.getOrElse(gen) - val deq = EnqIO(out_gen_, outl, outl) + val deq = EnqIO(out_gen.getOrElse(gen), outl, outl) /** The current amount of data in the queue */ //For now label the count the same level as the output's level val count = Output(UInt(log2Up(entries + 1).W), lbl=outl) From 51afc8d37c4a6d29fac999b38584d48668f06451 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Fri, 11 Aug 2017 13:18:41 -0400 Subject: [PATCH 30/35] Revert "Output label for decoupled Queues" Notes: Naming was handled incorrectly for DecoupledIOs and after Decoupled naming is fixed, this labeling is largely ineffective. The default Queue class should be replaced with HCQueue in the label-checked implementation since the internals need to be changed anyway. This reverts commit 59d1eb98fe44b8903673d1022fff87347fc1d71e. --- .../main/scala/chisel3/core/.Data.scala.swp | Bin 0 -> 32768 bytes .../src/main/scala/chisel3/core/Data.scala | 7 ++- .../scala/chisel3/util/.Decoupled.scala.swp | Bin 0 -> 20480 bytes src/main/scala/chisel3/util/Decoupled.scala | 55 +++++------------- 4 files changed, 18 insertions(+), 44 deletions(-) create mode 100644 chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp create mode 100644 src/main/scala/chisel3/util/.Decoupled.scala.swp diff --git a/chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp b/chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp new file mode 100644 index 0000000000000000000000000000000000000000..493ab02dc965e42966509d3e41bf99985f0af216 GIT binary patch literal 32768 zcmeI5e~@HXRma;TL|A@^SYiT`XF9W;L29Scq;t&X zQ=OHtKg~axjjr(D*QQCF+qkQ#dqEgaXPqDls#Hm8r*{Q;(AMXtYC`?4robbU0)u>M z>N$^ZT=5H+UnT^2=EO71Pd(}2Ba;?&uWJg_6sRdsQ=q0mO@W#MH3e!4JVGgu_b+U` zjJ}`e`#A>$;Dg{E@E0He+rcdO@}nD#_k&l0K4^hUz%#*=q ze*ayNJb*bBacG2>m}4sbho4cG>* z0{@92=F8xZz%j54mcY}%lfnJiJ?`up{W@!-XE6J5< z(d)BmHBxKVx1De)v|V3+o8d7hwNUlapp0v^&Rs=~P1oj@*|yD;58HEbe~^={pN7YS z+#dE`AxBKtE}1ZMWn3GD{l4w`5@w9l(3&wjk|eT0Y_^%3wc>Lk5`8JVx#a4Zifxvi zia@E&2WdP;qv6bFLZ(iTS<_@VlC(QxuGepfbB$RFqReWCT$1CqGh=SBox{>?Gs`Hg zSlnp3M>I7w^3)++I}3XK$R4$k?b$eQ4VB^_&6wT(omAx?wim;=8^+7+a(c)h9Y}h% zIW|&K;$}m2xjyz+*;cbJ z$!V-KP}+c}RLbC)jK1_(-*L2Nf_^^=ZDwSwrNkn?Vb!~C<1&@ei?W8)MnN7zR8l7t zo0>T3T3_MldM~GQ3e7@Ch->GrzkXql$=CX{KpxS5oqyR%GKjj;B_SrOk{V$l4bO%& z&CT#^9y@lh!_O_5V}1osYCp&;?`%40CU&Q3lFpc&K^zO^q?Z$J_PSZqjuxY%EOfpo z*l1JQ*=9Uu(!Jk+2W811?budZYH;Nr52AvbZZqz6+cBY?Q4-q)2tbX(jbseg4omHP zq@O>U1}t1XBb6U%y2j3!g;q0U)rXxhH=U%{494nG4D-{b0##ViZ`6 zrx~vKK@OYVWV9Ft6EOEQ&BGkFVzX$w8qaNr)>CLwCeDo66D->3?5Wj|0oT#@G@mpF z<707hB6bDxzM3EFD?iH$iLEUX;|J=>V=S~lPg@?*C-;j(oTo5h#r zrkl|JHMTFIRBU!Sr(@w)ae^c>h~>o!i`%k&l0Y`#CGU$o!N%m}Q8pu`f@hou<4XRu ztKzrJ?pW}y=ER_SJ<*~E335XkcCE4r*?Q=8ks7+W2_-Dp7w?z;1|=uTWY4KkSBu%8 z&`{XJnUv|taS*kgrqkY^hQ0ZIdwV7#;(UM8 z%*_+*7=#gmO#9~kAX{P2?Xl)2jr=j+Ke=hKN6TL5^lnE%ygUe&ZQHK)E$wHa)1h9_ zNs|n1Hs~DVW!Yo&2HR+`HV#;8_RQ_vz3;$o)jN;`n9MTS@*s>@!=nGsqN~3gi2je7 zte<~Cw|@Za2cP5JyTPA;SAyRFlKy3&{?rtxDNs|Ora(=BngTTiY6{d8s3}lWpr$}g zfis~%WnAW@p&ev%9GV1i$IdSumUD%+95NiiP+$!2%?ySljzaWrG0w}gZRQa6lBT9s zvzVCW#RfTITj(Z7G2QfbZ~{ZpAm@aTpF`$Xr|i$6>|;vMlK}ZWd3vjP*-Tm@Cs*Uu z25M%g%Q~spz{m!z|oY=W%e&=;qu0;R82&MmDMe#@f$D*g752E*f0K6akDtHcf2z~#v z;P=4m!Rx>s;1=*wFa@3n9tYmfS^uAdw}C_80Qg_d_1_EL1tM?}_!Q^)e+m8!yaT)# z+yJ(K^T7u>)4vV861)OD7d#t$#kcw6((d|GQ=q0mO@W#MH3e!4)D(EcP{8mhJ==zV zdso1b_qBT4-z?I;9a31(1zWn0n|32_W@G9^Ma0|E$d>fzs zHLx2z7W^ar`}ct^SO6D+2Dla9{a*t)SO#-oCwLzCTm1NM1N*^~!4~j#{P*t$7F-AZ z8GrqcfP27S0j^bS+zxI7hrv_87ofY){@vcE{|rT!O+2mhM2ugBFAQ^|U%1ZW5aRsi zOB0!TW;NB2G=m8ZH!b$X(wH@z*SXQS?3kHm%=UB{TN2*D%`n>&;)WfCInQL(;5LqX zNkp>EN|1Lmc(&p4v`xR%q9v@@O=kD6(WaQlE(e{pok<)^97AdQJL#%%uKh(uqaWve z=zbfMP58XHyyAP8pRhKj(52ioFP6Tx)C10$a)Ki^i67)zpA9ZM)BVFxlS5< z*Su4_E5FRv?l`)P*a-czQRm)CrKbEF;2&6cBoP+Uv0dlUSCB1F*VKwBRTXSS{pJs> z#rVHv;Z0&xR1@kX)V)+nytJSk{G@22V@Mn33~`FooMGm2G7LVaOsNe!fZH{34I^z3 zPp_c~K0HYm2hlN4WN++MvF~&?STXkML>ndE2A|;agxXzF8RLNoA1oJIGJ!DqX*& zECyXaH_oQna^j)OsEQ6N136gO;x9_{fO^q4qs78OzsSVm_ld~FQk1O94hWa&;Okoj ziyaSAeQSIXBp&wAmtx8;4KtA-ii$`YHdOnP!~U-$WWckM9_M%+XE;9N;JidY4X(bE zKFqF&nz>QJm*k+y<+)yC!_4+Qdy43)%n;b45kW;DjU0I4mO19@icDI1=RTiPvaYL^ zpGu&ih$%VcGK*9xL26q~j;m-(9Jl3>^Y^Y|s(LnGNn99`c#xWDGl=yEj<$miact~@ zU8x$6a0xQ>@mTnD;S}^E7cD z_o0PJ+H>J@6&-MGhYTiLBf6{S!WTK?^KIcx)>f@e+r~NIz*c_fG9CO#H*gn*PZvaz zDI?r^lw*4_*^AA^2FB*+-FAoF$BVSOo0uxv$$9Tf0GPbd0HSg$lr1gkGaO|>^HH~S zj^67=z*SqgNH>R$B_-=hf77U3NVvUt#XBLkJoPCbX!@R z8() zlU2ipA{$EPU&Pl{k)J~r&9k#uO01cLXp|wlB}GmZuS>46VBIp?8As}#Vqm_HgF#Un z4!{Ps3KwltT04iwb1c$U^#5n0bPl}!Kj#(Dd(rpb4EBKQz!SlD(D(lvd>gzI{0i6t zK99ct9`H`^dT=KYJHXe`_iq8az&7wr^!&dAZw3d!72rZ}FFO4#;0o~X=pLUfLZokg8X?Uu}bRj!v36v%NlK5?fq_FR`p+`6WQEdR*8-> z`{oyXxHNKui|s;s=ml%0nodD4UiZt9WsM$!5*GWMI=ZX_rckPD1lCtgFPwn-g)^O(bN_u7*go zO)ir_>~qw|ODctX3+-fnAo2yrF`%em=%$D(ijhOWk*LCw!Ma8aN23dUP(TPyiY4}Y zk1h@_e&(LkF@qY1V| zau0oRvU^x}{lQp?p0sK>JA|-ba??WEmr3R9Y^p4|UUm&}^^Cp9!rY(X^aG}rBgXdS zAU?*TmWePE?M3~U~8XSeAuou!Ph%MI;FbfVHs z$Qfq){yCi{GI9)m#4w8K3cX5Vz?zi+8^$sV862bzkwTR%%&YZk#<=gp_?{hsB{{2~ z+6%9fFz1%L3xbL0Y>3V>w~z2tX&_6)DLt7>rUi3tgS$vT|C05q%xJR8+IFX!RfEE; zs&V*o4=tgs*~h9ov4UugL@qO`tf!jJnq^%zMK5H{iGjxz&r=Fl4yj6WW^QDPx0y&$ zdtY*3&{^@SVW~~8>!2t@!&MFwrfi`wFR!OTpz*dA`mUN>n>gEH@fZD}wAI^8w5~I6rx)!dl$%yps$8McZGMx4@*=&-<#g9sXrfl7 z)>b)-i(MGwgR#b)dwZ{^v*s)kRkyzsMZrLu&8jp^y6QCR>N8hQxedNOWJNJI$^9fU zv_lV_6<2ycJ-sl$YrdJE2$z?ch`SP47Hc5mo)Y+$@@tEYCH2wt-cs&1_|s5ob0SG| zJavSzbw;kl*wpCk_TNI^Ql>BGX908ns1(%HNJb<*-AY5cMH=im zZhzK3V5wT+Xr>g-2+U_4uMYZLm}6fufYx2HLdlg#c!-O2O1rypkwxW7Cd5L$1CPQ@@;%_VI`YB@vl zswgJpEt^6>8}IAZJ3};I^?&f9)ui z#Ugf~Tn3dLLya}1eqJ88jvQc~&0ge7hJ@=2Rk6e$+72gxnel(ka|gBVD7e|lS7&6~ zWsl*$tm0%?_=p}A>-m2RCH7B6m*xDwxPSi*==-k+;sbCPJRSTD_&48> zr-BF3_g@2E1jN_>$>68KgXsNl2X6xj*aGfH=YJWv2K+2&fbXIEe-{*I|9A8IE^sZ7 zv;I|Z0z4BufDJ&-@_!vX9sCEn|JOhS9tAD{pF#J(6TA*AfvdpJfv;c#_%wI`d<@(N zJ_POse+}*cJ3tFO1$+ZL!9Czka66DQ|69RtfdtHg^TB(u8KmF^U=Dmw>;>TCU=Dm2 z`u;umDEJ5vdcPH%@yGEME`(trv9#8VFnMmdV9ulaGYh;lA$C8tNAaFpC&tcZhJ_Qi zlRL{ItUluZzbFPqm+!O^&8RFVWsL;B`26Q4evOvB!8YX2UuE^8(YWLB@fNsqA$NYX zM>uVBV$TF2GyeDUCv@Lu?-a3PMrJ*OraLtJ1u1q6n;U zDO~29#K;Jg3w8ZEWWh}+g~d&vOjmM=lAj$CKa5SCGAN}?Ib2Rr-^d7TYCfQp%A(Me zkyDwVV5vj94JozJ&DN%oS^jPoXX@6(r4`#NMNQYI%UdGqmE_))bo90&C3kzHgBhKe zrLNr`zE+1>%5E} zGVao^f_&~TG7KBJ&qA|u0k1Ge0eZeEUSNyNY_m##$AE8LTcN)SKUQ=qudD#KrTUb9SF#OLZH#b zvT#K7ddNwuWMqj%)WJQxV6Ju+`XfyolNVen{Q>JL&bzBARMF}z0~Fm^q0*$NySZsg zhmXdK7H`2R4n)JY|DR`VO_cGotTpu+cy} zn#WYymlXG`$$e1haAM^>fRG!&A>ghWaD^Q8F`eAU4HoRc*s%W*}daj1O+{E@q0O2Ly9OM7b%zf z(9ljm%gV>YJDHnX3rHG%vlKf^p+R9u7t?;J(r}ugM+V1}=(yBR((1lunWFOxyP<-J zFJ1@J>tTnB;aniswg(+?PE;Gczrf5j1sO;F2iszQcM_1ZCzKaD!zH-~wkcP7B7I8h zV5TA|O>i;WAmA2h(Z8JaVY)P8bYM6PgC0ZXXrmkehh z2Qj$(={l3oQ7szX8dOsv@4 zLdOAQE*?I*kFp*(pGl9)NsK7pc2%#L#?{Ci5NgszRaaec{Oe5L%rTqFiV{x+9cQ7v zjja?&LRX*VR|fOYDD-&J1oSdEPA2eYN$4fj9pUd?EL6{rSWo?kHK)E}B@vjp OWtpPt`~dDOX#5{OZ|>g! literal 0 HcmV?d00001 diff --git a/chiselFrontend/src/main/scala/chisel3/core/Data.scala b/chiselFrontend/src/main/scala/chisel3/core/Data.scala index 1fbb70a..a8e39b9 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Data.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Data.scala @@ -59,8 +59,11 @@ object Output { } } object Flipped { - def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = - apply(source, UnknownLabel) + def apply[T<:Data](source: T)(implicit compileOptions: CompileOptions): T = { + val target = source.chiselCloneType + Data.setFirrtlDirection(target, Data.getFirrtlDirection(source).flip) + Binding.bind(target, FlippedBinder, "Error: Cannot flip ") + } def apply[T<:Data](source: T, lbl: Label)(implicit compileOptions: CompileOptions): T = { val target = source.chiselCloneType diff --git a/src/main/scala/chisel3/util/.Decoupled.scala.swp b/src/main/scala/chisel3/util/.Decoupled.scala.swp new file mode 100644 index 0000000000000000000000000000000000000000..68066bba41c3c8e9529a87eb11b5d55e75e37985 GIT binary patch literal 20480 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 literal 0 HcmV?d00001 diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index b09d2ee..81f55b5 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -144,31 +144,25 @@ object Irrevocable } object EnqIO { - def apply[T<:Data](gen: T, rdyl: Label = UnknownLabel, vall: Label=UnknownLabel): DecoupledIO[T] = Decoupled(gen, rdyl, vall) + def apply[T<:Data](gen: T): DecoupledIO[T] = Decoupled(gen) } object DeqIO { - def apply[T<:Data](gen: T, rdyl: Label = UnknownLabel, vall: Label=UnknownLabel): DecoupledIO[T] = Flipped(Decoupled(gen, rdyl, vall)) + def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen)) } /** An I/O Bundle for Queues * @param gen The type of data to queue - * @param out_gen The type of the output of the queue - * @param entries The max number of entries in the queue - * @param inl The label of the queue's input - * @param outl The label of the queue's output*/ -class QueueIO[T <: Data](gen: T, entries: Int, inl: Label = UnknownLabel, - outl: Label = UnknownLabel, out_gen: Option[T] = None) extends Bundle + * @param entries The max number of entries in the queue */ +class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle { - //For some reason, the Enq and Deq names are flipped.... /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ - val enq = DeqIO(gen, inl, inl) + val enq = DeqIO(gen) /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ - val deq = EnqIO(out_gen.getOrElse(gen), outl, outl) + val deq = EnqIO(gen) /** The current amount of data in the queue */ - //For now label the count the same level as the output's level - val count = Output(UInt(log2Up(entries + 1).W), lbl=outl) + val count = Output(UInt(log2Up(entries + 1).W)) - override def cloneType = new QueueIO(gen, entries, inl, outl, out_gen).asInstanceOf[this.type] + override def cloneType = new QueueIO(gen, entries).asInstanceOf[this.type] } /** A hardware module implementing a Queue @@ -178,8 +172,6 @@ class QueueIO[T <: Data](gen: T, entries: Int, inl: Label = UnknownLabel, * combinationally coupled. * @param flow True if the inputs can be consumed on the same cycle (the inputs "flow" through the queue immediately). * The ''valid'' signals are coupled. - * @param inl The label of the queue's input - * @param outl The label of the queue's output * * @example {{{ * val q = new Queue(UInt(), 16) @@ -191,14 +183,10 @@ class Queue[T <: Data](gen: T, val entries: Int, pipe: Boolean = false, flow: Boolean = false, - override_reset: Option[Bool] = None, - inl: Label = UnknownLabel, - outl: Label = UnknownLabel, - out_gen: Option[T] = None) + override_reset: Option[Bool] = None) extends Module(override_reset=override_reset) { - def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool, inl: Label, outl: Label, out_gen: T) = this(gen, entries, pipe, flow, Some(_reset), inl, outl, Some(out_gen)) - - val io = IO(new QueueIO(gen, entries, inl, outl, out_gen)) + + val io = IO(new QueueIO(gen, entries)) private val ram = Mem(entries, gen) private val enq_ptr = Counter(entries) @@ -270,13 +258,8 @@ object Queue enq: ReadyValidIO[T], entries: Int = 2, pipe: Boolean = false, - flow: Boolean = false, - inl: Label = UnknownLabel, - outl: Label = UnknownLabel, - deq: Option[ReadyValidIO[T]] = None): DecoupledIO[T] = { - - val deq_ = deq.getOrElse(enq) - val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow, inl = inl, outl = outl, out_gen = Some(deq_.bits.cloneType))) + flow: Boolean = false): DecoupledIO[T] = { + val q = Module(new Queue(enq.bits.cloneType, entries, pipe, flow)) q.io.enq.valid := enq.valid // not using <> so that override is allowed q.io.enq.bits := enq.bits enq.ready := q.io.enq.ready @@ -293,7 +276,6 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): IrrevocableIO[T] = { - //This module isn't really used in labeling yet, so just use enq type as the deq. val deq = apply(enq, entries, pipe, flow) val irr = Wire(new IrrevocableIO(deq.bits)) irr.bits := deq.bits @@ -302,14 +284,3 @@ object Queue irr } } - -/** - * Factory for constructing a labeled queue that has an deq type specified - * */ -//object LabeledQueue -//{ -// /** Create a queue and supply a DecoupledIO containing the product. */ -// def apply[T <: Data]( -// enq: ReadyValidIO[T], -// deq: ReadyValidIO[T], -// From 98446766d24f34895d8e6562839889ca9319b19e Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Tue, 15 Aug 2017 19:27:08 -0400 Subject: [PATCH 31/35] Nextifying support in chisel3 --- .../src/main/scala/chisel3/core/Bits.scala | 12 ++++++++++-- .../src/main/scala/chisel3/internal/Builder.scala | 6 ++++++ .../src/main/scala/chisel3/internal/firrtl/IR.scala | 1 + .../internal/sourceinfo/SourceInfoTransform.scala | 8 ++++++++ src/main/scala/chisel3/compatibility.scala | 1 + src/main/scala/chisel3/internal/firrtl/Emitter.scala | 2 ++ src/main/scala/chisel3/package.scala | 1 + 7 files changed, 29 insertions(+), 2 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala index 2654359..d7b2546 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Bits.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Bits.scala @@ -5,10 +5,10 @@ package chisel3.core import scala.language.experimental.macros import chisel3.internal._ -import chisel3.internal.Builder.{pushCommand, pushOp, pushDeclass, pushEndorse} +import chisel3.internal.Builder.{pushCommand, pushOp, pushDeclass, pushEndorse, pushNext} import chisel3.internal.firrtl._ import chisel3.internal.sourceinfo.{SourceInfo, DeprecatedSourceInfo, SourceInfoTransform, SourceInfoWhiteboxTransform, - UIntTransform, MuxTransform, DeclassifyTransform, EndorseTransform} + UIntTransform, MuxTransform, DeclassifyTransform, EndorseTransform, NextTransform} import chisel3.internal.firrtl.PrimOp._ // TODO: remove this once we have CompileOptions threaded through the macro system. import chisel3.core.ExplicitCompileOptions.NotStrict @@ -790,6 +790,14 @@ object Endorse { } } +object Next { + def apply[T <: Data](arg: T): T = macro NextTransform.apply[T] + def do_apply[T <: Data](arg: T)(implicit sourceInfo: SourceInfo): T = { + val dtype = arg.cloneType + pushNext(DefNext(sourceInfo, dtype, arg.ref)) + } +} + object Mux { /** Creates a mux, whose output is one of the inputs depending on the * value of the condition. diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index e870405..b0b8913 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -218,6 +218,12 @@ private[chisel3] object Builder { pushCommand(cmd).id } + def pushNext[ T <: Data](cmd: DefNext[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) def warning(m: => String): Unit = errors.warning(m) diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index c890980..9446be0 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -263,6 +263,7 @@ abstract class Definition extends Command { case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition case class DefDeclass[T <: Data](sourceInfo: SourceInfo, id: T, arg: Arg, lbl: Label) extends Definition case class DefEndorse[T <: Data](sourceInfo: SourceInfo, id: T, arg: Arg, lbl: Label) extends Definition +case class DefNext[T <: Data](sourceInfo: SourceInfo, id: T, arg: Arg) extends Definition case class DefInvalid(sourceInfo: SourceInfo, arg: Arg) extends Command case class DefWire(sourceInfo: SourceInfo, id: Data, lbl: Label) extends Definition case class DefReg(sourceInfo: SourceInfo, id: Data, clock: Arg, lbl: Label) extends Definition diff --git a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala index 0b7de8c..9dbd158 100644 --- a/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala +++ b/coreMacros/src/main/scala/chisel3/internal/sourceinfo/SourceInfoTransform.scala @@ -83,6 +83,14 @@ class EndorseTransform(val c: Context) extends SourceInfoTransformMacro { } } +class NextTransform(val c: Context) extends SourceInfoTransformMacro { + import c.universe._ + def apply[T: c.WeakTypeTag](arg: c.Tree): c.Tree = { + val tpe = weakTypeOf[T] + q"$thisObj.do_apply[$tpe]($arg)($implicitSourceInfo)" + } +} + class MuxTransform(val c: Context) extends SourceInfoTransformMacro { import c.universe._ def apply[T: c.WeakTypeTag](cond: c.Tree, con: c.Tree, alt: c.Tree): c.Tree = { diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 8f58bf1..9a12010 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -26,6 +26,7 @@ package object Chisel { // scalastyle:ignore package.object.name val MeetLabelComp = chisel3.core.MeetLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse + val Next = chisel3.core.Next // Not originally part of compatibility.scala diff --git a/src/main/scala/chisel3/internal/firrtl/Emitter.scala b/src/main/scala/chisel3/internal/firrtl/Emitter.scala index 5937067..5700fd7 100644 --- a/src/main/scala/chisel3/internal/firrtl/Emitter.scala +++ b/src/main/scala/chisel3/internal/firrtl/Emitter.scala @@ -32,6 +32,8 @@ private class Emitter(circuit: Circuit, compileTopOnly: Boolean) { case e: DefEndorse[_] => val lbl_s = e.lbl.fullName(ctx) s"node ${e.name} ${lbl_s} = endorse(${e.arg.fullName(ctx)}, ${lbl_s})" + case e: DefNext[_] => + s"node ${e.name} = next(${e.arg.fullName(ctx)})" case e: DefWire => s"wire ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}" case e: DefReg => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}, ${e.clock.fullName(ctx)}" case e: DefRegInit => s"reg ${e.name} : ${e.lbl.fullName(ctx)}${e.id.toType(ctx)}, ${e.clock.fullName(ctx)} with : (reset => (${e.reset.fullName(ctx)}, ${e.init.fullName(ctx)}))" diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 2d50f32..80dd8af 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -35,6 +35,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val MeetLabelComp = chisel3.core.MeetLabelComp val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse + val Next = chisel3.core.Next // Components val C = chisel3.core.C From c2aa5edb3eacac5d3b2e0148ef01edd579e8d0dc Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 16 Aug 2017 11:38:47 -0400 Subject: [PATCH 32/35] Counters can be labeled. --- src/main/scala/chisel3/util/Counter.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 6d59eaa..4c02e31 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -10,9 +10,9 @@ import chisel3._ * @param n number of counts before the counter resets (or one more than the * maximum output value of the counter), need not be a power of two */ -class Counter(val n: Int) { +class Counter(val n: Int, l: Label=UnknownLabel) { require(n >= 0) - val value = if (n > 1) Reg(init=0.U(log2Up(n).W)) else 0.U + val value = if (n > 1) Reg(init=0.U(log2Up(n).W), lbl = l) else 0.U /** Increment the counter, returning whether the counter currently is at the * maximum and will wrap. The incremented value is registered and will be @@ -36,7 +36,7 @@ object Counter { /** Instantiate a [[Counter! counter]] with the specified number of counts. */ - def apply(n: Int): Counter = new Counter(n) + def apply(n: Int, l: Label = UnknownLabel): Counter = new Counter(n, l) /** Instantiate a [[Counter! counter]] with the specified number of counts and a gate. * From 285fbd058383dba5dc314a6bc36aa24359393ee0 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 17 Aug 2017 17:43:26 -0400 Subject: [PATCH 33/35] chisel-side for vectorized labels --- .gitignore | 1 + .../src/main/scala/chisel3/core/.Data.scala.swp | Bin 32768 -> 0 bytes .../src/main/scala/chisel3/core/Aggregate.scala | 3 ++- .../main/scala/chisel3/internal/Builder.scala | 1 + .../main/scala/chisel3/internal/firrtl/IR.scala | 5 +++++ .../scala/chisel3/util/.Decoupled.scala.swp | Bin 20480 -> 0 bytes src/main/scala/chisel3/util/Arbiter.scala | 2 +- 7 files changed, 10 insertions(+), 2 deletions(-) delete mode 100644 chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp delete mode 100644 src/main/scala/chisel3/util/.Decoupled.scala.swp diff --git a/.gitignore b/.gitignore index b4fc65d..9cc0d18 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ generated/ .idea target/ *.iml +*.swp diff --git a/chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp b/chiselFrontend/src/main/scala/chisel3/core/.Data.scala.swp deleted file mode 100644 index 493ab02dc965e42966509d3e41bf99985f0af216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 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 OWtpPt`~dDOX#5{OZ|>g! diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 049e90a..1413fcd 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -265,7 +265,7 @@ sealed class Vec[T <: Data] private (gen: => T, val length: Int) } override def _onModuleClose: Unit = { - sample_element.setRef(this, 0) + sample_element.setRefBinder(this) } } @@ -584,6 +584,7 @@ trait BitsLevelNamer { case ax: Index => argIsTemp(ax.imm) || strTmp(ax.name) case ax: Node => !ax.id.refSet || strTmp(ax.name) case ax: LitArg => false + case ax: BindIndex => argIsTemp(ax.imm) } diff --git a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala index b0b8913..5878d4e 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/Builder.scala @@ -106,6 +106,7 @@ private[chisel3] trait HasId extends InstanceId { 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 setRefBinder(parent: HasId): Unit = setRef(BindIndex(Node(parent))) // private[chisel3] def setRef(parent: HasId, names: Seq[String]): Unit = { // var newRef = Node(parent) // for(name <- names) { diff --git a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala index 9446be0..47926bd 100644 --- a/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala +++ b/chiselFrontend/src/main/scala/chisel3/internal/firrtl/IR.scala @@ -120,6 +120,11 @@ case class Index(imm: Arg, value: Arg) extends Arg { override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[${value.fullName(ctx)}]" def pprint = s"Index(${imm.name}, ${value.name})" } +case class BindIndex(imm: Arg) extends Arg { + def name: String = s"[_]" + override def fullName(ctx: Component): String = s"${imm.fullName(ctx)}[_]" + def pprint = s"Index(${imm.name}, _)" +} sealed trait Bound sealed trait NumericBound[T] extends Bound { diff --git a/src/main/scala/chisel3/util/.Decoupled.scala.swp b/src/main/scala/chisel3/util/.Decoupled.scala.swp deleted file mode 100644 index 68066bba41c3c8e9529a87eb11b5d55e75e37985..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20480 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 diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 20d9c54..3cf7d26 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -24,7 +24,7 @@ class ArbiterIO[T <: Data](gen: T, out_gen: T, n: Int, inl: Label, outl: Label) /** Arbiter Control determining which producer has access */ -private object ArbiterCtrl { +object ArbiterCtrl { def apply(request: Seq[Bool]): Seq[Bool] = request.length match { case 0 => Seq() case 1 => Seq(true.B) From 04b6462948d92cb664f829464b21b8dc145a031f Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Wed, 23 Aug 2017 17:05:02 -0400 Subject: [PATCH 34/35] A way to avoid cool new vectorized deptypes --- .../main/scala/chisel3/core/Aggregate.scala | 23 +++++++++++++++++-- src/main/scala/chisel3/compatibility.scala | 2 ++ src/main/scala/chisel3/package.scala | 2 ++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala index 1413fcd..93e62b5 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Aggregate.scala @@ -44,7 +44,7 @@ object Vec { * @note elements are NOT assigned by default and have no value */ def apply[T <: Data](n: Int, gen: T): Vec[T] = macro VecTransform.apply_ngen; - + def do_apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = { if ( gen.isLit ) { Vec(Seq.fill(n)(gen)) @@ -152,6 +152,24 @@ object Vec { } } +class MonoLabelVec[T <: Data](gen: => T, length: Int) extends Vec[T](gen, length) { + override def _onModuleClose: Unit = { + sample_element.setRef(this, 0) + } + + override def cloneType: this.type = { + new MonoLabelVec(gen.cloneType, length).asInstanceOf[this.type] + } +} + +object MonoLabelVec { + def apply[T <: Data](n: Int, gen: T): Vec[T] = macro VecTransform.apply_ngen; + + def do_apply[T <: Data](n: Int, gen: T)(implicit sourceInfo: SourceInfo, compileOptions: CompileOptions): Vec[T] = { + new MonoLabelVec(gen.chiselCloneType, n) + } +} + /** A vector (array) of [[Data]] elements. Provides hardware versions of various * collection transformation functions found in software array implementations. * @@ -161,8 +179,9 @@ object Vec { * @note Vecs, unlike classes in Scala's collection library, are propagated * intact to FIRRTL as a vector type, which may make debugging easier */ -sealed class Vec[T <: Data] private (gen: => T, val length: Int) +sealed class Vec[T <: Data] protected (gen: => T, val length: Int) extends Aggregate with VecLike[T] { + // Note: the constructor takes a gen() function instead of a Seq to enforce // that all elements must be the same and because it makes FIRRTL generation // simpler. diff --git a/src/main/scala/chisel3/compatibility.scala b/src/main/scala/chisel3/compatibility.scala index 9a12010..8a094e2 100644 --- a/src/main/scala/chisel3/compatibility.scala +++ b/src/main/scala/chisel3/compatibility.scala @@ -65,6 +65,8 @@ package object Chisel { // scalastyle:ignore package.object.name val Vec = chisel3.core.Vec type Vec[T <: Data] = chisel3.core.Vec[T] type VecLike[T <: Data] = chisel3.core.VecLike[T] + val MonoLabelVec = chisel3.core.MonoLabelVec + type MonoLabelVec[T <: Data] = chisel3.core.MonoLabelVec[T] type Record = chisel3.core.Record type Bundle = chisel3.core.Bundle diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index 80dd8af..a094d18 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -45,6 +45,8 @@ package object chisel3 { // scalastyle:ignore package.object.name type Aggregate = chisel3.core.Aggregate val Vec = chisel3.core.Vec type Vec[T <: Data] = chisel3.core.Vec[T] + val MonoLabelVec = chisel3.core.MonoLabelVec + type MonoLabelVec[T <: Data] = chisel3.core.MonoLabelVec[T] type VecLike[T <: Data] = chisel3.core.VecLike[T] type Bundle = chisel3.core.Bundle type Record = chisel3.core.Record From c390a740a41cd8c21c2d3f53ca3040795c89e636 Mon Sep 17 00:00:00 2001 From: Andrew Ferraiuolo Date: Thu, 24 Aug 2017 18:06:49 -0400 Subject: [PATCH 35/35] conditional labels --- chiselFrontend/src/main/scala/chisel3/core/Label.scala | 6 ++++++ src/main/scala/chisel3/package.scala | 1 + 2 files changed, 7 insertions(+) diff --git a/chiselFrontend/src/main/scala/chisel3/core/Label.scala b/chiselFrontend/src/main/scala/chisel3/core/Label.scala index 5a26d59..26a79b0 100644 --- a/chiselFrontend/src/main/scala/chisel3/core/Label.scala +++ b/chiselFrontend/src/main/scala/chisel3/core/Label.scala @@ -90,6 +90,12 @@ object HLevel { } } +case class IfL(id: HasId)(tc: LabelComp)(fc: LabelComp) extends LabelComp { + def name = s"IFL(${id.getRef.name})(${tc.name})(${fc.name})" + def fullName(ctx: Component) = + s"IFL(${id.getRef.fullName(ctx)})(${tc.fullName(ctx)})(${fc.fullName(ctx)})" +} + case class VLabel(id: HasId) extends LabelComp { def name = s"[[${id.getRef.name}]]V" def fullName(ctx: Component) = s"[[${id.getRef.fullName(ctx)}]]V" diff --git a/src/main/scala/chisel3/package.scala b/src/main/scala/chisel3/package.scala index a094d18..6863a44 100644 --- a/src/main/scala/chisel3/package.scala +++ b/src/main/scala/chisel3/package.scala @@ -33,6 +33,7 @@ package object chisel3 { // scalastyle:ignore package.object.name val VLabel = chisel3.core.VLabel val JoinLabelComp = chisel3.core.JoinLabelComp val MeetLabelComp = chisel3.core.MeetLabelComp + val IfL = chisel3.core.IfL val Declassify = chisel3.core.Declassify val Endorse = chisel3.core.Endorse val Next = chisel3.core.Next