From d408d73a171535bd7c2ba9d0037c194022b8a62f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 20 Jun 2016 11:08:46 -0700 Subject: Rename chisel3 package. --- src/main/scala/chisel3/util/Arbiter.scala | 119 +++++++++++++ src/main/scala/chisel3/util/BitPat.scala | 89 ++++++++++ src/main/scala/chisel3/util/Bitwise.scala | 74 +++++++++ src/main/scala/chisel3/util/Cat.scala | 21 +++ src/main/scala/chisel3/util/CircuitMath.scala | 28 ++++ src/main/scala/chisel3/util/Conditional.scala | 73 ++++++++ src/main/scala/chisel3/util/Counter.scala | 46 +++++ src/main/scala/chisel3/util/Decoupled.scala | 185 +++++++++++++++++++++ src/main/scala/chisel3/util/Enum.scala | 23 +++ .../scala/chisel3/util/ImplicitConversions.scala | 10 ++ src/main/scala/chisel3/util/LFSR.scala | 24 +++ src/main/scala/chisel3/util/Lookup.scala | 19 +++ src/main/scala/chisel3/util/Math.scala | 44 +++++ src/main/scala/chisel3/util/Mux.scala | 64 +++++++ src/main/scala/chisel3/util/OneHot.scala | 64 +++++++ src/main/scala/chisel3/util/Reg.scala | 57 +++++++ src/main/scala/chisel3/util/TransitName.scala | 22 +++ src/main/scala/chisel3/util/Valid.scala | 61 +++++++ 18 files changed, 1023 insertions(+) create mode 100644 src/main/scala/chisel3/util/Arbiter.scala create mode 100644 src/main/scala/chisel3/util/BitPat.scala create mode 100644 src/main/scala/chisel3/util/Bitwise.scala create mode 100644 src/main/scala/chisel3/util/Cat.scala create mode 100644 src/main/scala/chisel3/util/CircuitMath.scala create mode 100644 src/main/scala/chisel3/util/Conditional.scala create mode 100644 src/main/scala/chisel3/util/Counter.scala create mode 100644 src/main/scala/chisel3/util/Decoupled.scala create mode 100644 src/main/scala/chisel3/util/Enum.scala create mode 100644 src/main/scala/chisel3/util/ImplicitConversions.scala create mode 100644 src/main/scala/chisel3/util/LFSR.scala create mode 100644 src/main/scala/chisel3/util/Lookup.scala create mode 100644 src/main/scala/chisel3/util/Math.scala create mode 100644 src/main/scala/chisel3/util/Mux.scala create mode 100644 src/main/scala/chisel3/util/OneHot.scala create mode 100644 src/main/scala/chisel3/util/Reg.scala create mode 100644 src/main/scala/chisel3/util/TransitName.scala create mode 100644 src/main/scala/chisel3/util/Valid.scala (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala new file mode 100644 index 00000000..3723f2a9 --- /dev/null +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -0,0 +1,119 @@ +// See LICENSE for license details. + +/** Arbiters in all shapes and sizes. + */ + +package chisel.util + +import chisel._ + +/** An I/O bundle for the Arbiter */ +class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { + val in = Vec(n, Decoupled(gen)).flip + val out = Decoupled(gen) + val chosen = UInt(OUTPUT, log2Up(n)) +} + +/** Arbiter Control determining which producer has access */ +private object ArbiterCtrl +{ + def apply(request: Seq[Bool]): Seq[Bool] = request.length match { + case 0 => Seq() + case 1 => Seq(Bool(true)) + case _ => Bool(true) +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) + } +} + +abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool]) extends Module { + def grant: Seq[Bool] + def choice: UInt + val io = new ArbiterIO(gen, n) + + io.chosen := choice + io.out.valid := io.in(io.chosen).valid + io.out.bits := io.in(io.chosen).bits + + if (count > 1) { + val lockCount = Counter(count) + val lockIdx = Reg(UInt()) + val locked = lockCount.value =/= UInt(0) + val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(Bool(true)) + + when (io.out.fire() && wantsLock) { + lockIdx := io.chosen + lockCount.inc() + } + + when (locked) { io.chosen := lockIdx } + for ((in, (g, i)) <- io.in zip grant.zipWithIndex) + in.ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready + } else { + for ((in, g) <- io.in zip grant) + in.ready := g && io.out.ready + } +} + +class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) + extends LockingArbiterLike[T](gen, n, count, needsLock) { + lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) + lazy val grantMask = (0 until n).map(UInt(_) > lastGrant) + lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } + + override def grant: Seq[Bool] = { + val ctrl = ArbiterCtrl((0 until n).map(i => validMask(i)) ++ io.in.map(_.valid)) + (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) + } + + override lazy val choice = Wire(init=UInt(n-1)) + for (i <- n-2 to 0 by -1) + when (io.in(i).valid) { choice := UInt(i) } + for (i <- n-1 to 1 by -1) + when (validMask(i)) { choice := UInt(i) } +} + +class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) + extends LockingArbiterLike[T](gen, n, count, needsLock) { + def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) + + override lazy val choice = Wire(init=UInt(n-1)) + for (i <- n-2 to 0 by -1) + when (io.in(i).valid) { choice := UInt(i) } +} + +/** Hardware module that is used to sequence n producers into 1 consumer. + Producers are chosen in round robin order. + + Example usage: + val arb = new RRArbiter(2, UInt()) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) + +/** Hardware module that is used to sequence n producers into 1 consumer. + Priority is given to lower producer + + Example usage: + val arb = Module(new Arbiter(2, UInt())) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class Arbiter[T <: Data](gen: T, n: Int) extends Module { + val io = new ArbiterIO(gen, n) + + io.chosen := UInt(n-1) + io.out.bits := io.in(n-1).bits + for (i <- n-2 to 0 by -1) { + when (io.in(i).valid) { + io.chosen := UInt(i) + io.out.bits := io.in(i).bits + } + } + + val grant = ArbiterCtrl(io.in.map(_.valid)) + for ((in, g) <- io.in zip grant) + in.ready := g && io.out.ready + io.out.valid := !grant.last || io.in.last.valid +} diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala new file mode 100644 index 00000000..13bbe1b0 --- /dev/null +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -0,0 +1,89 @@ +// See LICENSE for license details. + +package chisel.util + +import scala.language.experimental.macros + +import chisel._ +import chisel.internal.sourceinfo.{SourceInfo, SourceInfoTransform} + +object BitPat { + /** Parses a bit pattern string into (bits, mask, width). + * + * @return bits the literal value, with don't cares being 0 + * @return mask the mask bits, with don't cares being 0 and cares being 1 + * @return width the number of bits in the literal, including values and + * don't cares. + */ + private def parse(x: String): (BigInt, BigInt, Int) = { + // Notes: + // While Verilog Xs also handle octal and hex cases, there isn't a + // compelling argument and no one has asked for it. + // If ? parsing is to be exposed, the return API needs further scrutiny + // (especially with things like mask polarity). + require(x.head == 'b', "BitPats must be in binary and be prefixed with 'b'") + var bits = BigInt(0) + var mask = BigInt(0) + for (d <- x.tail) { + if (d != '_') { + require("01?".contains(d), "Literal: " + x + " contains illegal character: " + d) + mask = (mask << 1) + (if (d == '?') 0 else 1) + bits = (bits << 1) + (if (d == '1') 1 else 0) + } + } + (bits, mask, x.length - 1) + } + + /** Creates a [[BitPat]] literal from a string. + * + * @param n the literal value as a string, in binary, prefixed with 'b' + * @note legal characters are '0', '1', and '?', as well as '_' as white + * space (which are ignored) + */ + def apply(n: String): BitPat = { + val (bits, mask, width) = parse(n) + new BitPat(bits, mask, width) + } + + /** Creates a [[BitPat]] of all don't cares of the specified bitwidth. */ + def dontCare(width: Int): BitPat = BitPat("b" + ("?" * width)) + + @deprecated("Use BitPat.dontCare", "chisel3") + def DC(width: Int): BitPat = dontCare(width) // scalastyle:ignore method.name + + /** Allows BitPats to be used where a UInt is expected. + * + * @note the BitPat must not have don't care bits (will error out otherwise) + */ + def bitPatToUInt(x: BitPat): UInt = { + require(x.mask == (BigInt(1) << x.getWidth) - 1) + UInt(x.value, x.getWidth) + } + + /** Allows UInts to be used where a BitPat is expected, useful for when an + * interface is defined with BitPats but not all cases need the partial + * matching capability. + * + * @note the UInt must be a literal + */ + def apply(x: UInt): BitPat = { + require(x.isLit) + BitPat("b" + x.litValue.toString(2)) + } +} + +// TODO: Break out of Core? (this doesn't involve FIRRTL generation) +/** Bit patterns are literals with masks, used to represent values with don't + * cares. Equality comparisons will ignore don't care bits (for example, + * BitPat(0b10?1) === UInt(0b1001) and UInt(0b1011)). + */ +sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { + def getWidth: Int = width + def === (that: UInt): Bool = macro SourceInfoTransform.thatArg + def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + def != (that: UInt): Bool = macro SourceInfoTransform.thatArg + + def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = UInt(value) === (that & UInt(mask)) + def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) + def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that +} diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala new file mode 100644 index 00000000..d7d62ea3 --- /dev/null +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -0,0 +1,74 @@ +// See LICENSE for license details. + +/** Miscellaneous circuit generators operating on bits. + */ + +package chisel.util + +import chisel._ +import chisel.core.SeqUtils + +object FillInterleaved +{ + def apply(n: Int, in: UInt): UInt = apply(n, in.toBools) + def apply(n: Int, in: Seq[Bool]): UInt = Vec(in.map(Fill(n, _))).toBits +} + +/** Returns the number of bits set (i.e value is 1) in the input signal. + */ +object PopCount +{ + def apply(in: Iterable[Bool]): UInt = SeqUtils.count(in.toSeq) + def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_))) +} + +/** Fill fans out a UInt to multiple copies */ +object Fill { + /** Fan out x n times */ + def apply(n: Int, x: UInt): UInt = { + n match { + case 0 => UInt(width=0) + case 1 => x + case y if n > 1 => + val p2 = Array.ofDim[UInt](log2Up(n + 1)) + p2(0) = x + for (i <- 1 until p2.length) + p2(i) = Cat(p2(i-1), p2(i-1)) + Cat((0 until log2Up(y + 1)).filter(i => (y & (1 << i)) != 0).map(p2(_))) + case _ => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.") + } + } + /** Fan out x n times */ + def apply(n: Int, x: Bool): UInt = + if (n > 1) { + UInt(0,n) - x + } else { + apply(n, x: UInt) + } +} + +/** Litte/big bit endian convertion: reverse the order of the bits in a UInt. +*/ +object Reverse +{ + private def doit(in: UInt, length: Int): UInt = { + if (length == 1) { + in + } else if (isPow2(length) && length >= 8 && length <= 64) { + // This esoterica improves simulation performance + var res = in + var shift = length >> 1 + var mask = UInt((BigInt(1) << length) - 1, length) + do { + mask = mask ^ (mask(length-shift-1,0) << shift) + res = ((res >> shift) & mask) | ((res(length-shift-1,0) << shift) & ~mask) + shift = shift >> 1 + } while (shift > 0) + res + } else { + val half = (1 << log2Up(length))/2 + Cat(doit(in(half-1,0), half), doit(in(length-1,half), length-half)) + } + } + def apply(in: UInt): UInt = doit(in, in.getWidth) +} diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala new file mode 100644 index 00000000..b47da706 --- /dev/null +++ b/src/main/scala/chisel3/util/Cat.scala @@ -0,0 +1,21 @@ +// See LICENSE for license details. + +package chisel.util + +import chisel._ +import chisel.core.SeqUtils + +object Cat { + /** Combine data elements together + * @param a Data to combine with + * @param r any number of other Data elements to be combined in order + * @return A UInt which is all of the bits combined together + */ + def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList) + + /** Combine data elements together + * @param r any number of other Data elements to be combined in order + * @return A UInt which is all of the bits combined together + */ + def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse) +} diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala new file mode 100644 index 00000000..c3b94fdb --- /dev/null +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -0,0 +1,28 @@ +// See LICENSE for license details. + +/** Circuit-land math operations. + */ + +package chisel.util + +import chisel._ + +/** Compute Log2 with truncation of a UInt in hardware using a Mux Tree + * An alternative interpretation is it computes the minimum number of bits needed to represent x + * @example + * {{{ data_out := Log2(data_in) }}} + * @note Truncation is used so Log2(UInt(12412)) = 13*/ +object Log2 { + /** Compute the Log2 on the least significant n bits of x */ + def apply(x: Bits, width: Int): UInt = { + if (width < 2) { + UInt(0) + } else if (width == 2) { + x(1) + } else { + Mux(x(width-1), UInt(width-1), apply(x, width-1)) + } + } + + def apply(x: Bits): UInt = apply(x, x.getWidth) +} diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala new file mode 100644 index 00000000..01c12799 --- /dev/null +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -0,0 +1,73 @@ +// See LICENSE for license details. + +/** Conditional blocks. + */ + +package chisel.util + +import scala.language.reflectiveCalls +import scala.language.experimental.macros +import scala.reflect.runtime.universe._ +import scala.reflect.macros.blackbox._ + +import chisel._ + +/** This is identical to [[Chisel.when when]] with the condition inverted */ +object unless { // scalastyle:ignore object.name + def apply(c: Bool)(block: => Unit) { + when (!c) { block } + } +} + +class SwitchContext[T <: Bits](cond: T) { + def is(v: Iterable[T])(block: => Unit) { + if (!v.isEmpty) when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { block } + } + def is(v: T)(block: => Unit) { is(Seq(v))(block) } + def is(v: T, vr: T*)(block: => Unit) { is(v :: vr.toList)(block) } +} + +/** An object for separate cases in [[Chisel.switch switch]] + * It is equivalent to a [[Chisel.when$ when]] block comparing to the condition + * Use outside of a switch statement is illegal */ +object is { // scalastyle:ignore object.name + // Begin deprecation of non-type-parameterized is statements. + def apply(v: Iterable[Bits])(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } + + def apply(v: Bits)(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } + + def apply(v: Bits, vr: Bits*)(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } +} + +/** Conditional logic to form a switch block + * @example + * {{{ ... // default values here + * switch ( myState ) { + * is( state1 ) { + * ... // some logic here + * } + * is( state2 ) { + * ... // some logic here + * } + * } }}}*/ +object switch { // scalastyle:ignore object.name + def apply[T <: Bits](cond: T)(x: => Unit): Unit = macro impl + def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._ + val sc = c.universe.internal.reificationSupport.freshTermName("sc") + def extractIsStatement(tree: Tree): List[c.universe.Tree] = tree match { + // TODO: remove when Chisel compatibility package is removed + case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + case q"chisel.util.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") + } + val q"..$body" = x + val ises = body.flatMap(extractIsStatement(_)) + q"""{ val $sc = new SwitchContext($cond); ..$ises }""" + } +} diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala new file mode 100644 index 00000000..1c0b0203 --- /dev/null +++ b/src/main/scala/chisel3/util/Counter.scala @@ -0,0 +1,46 @@ +// See LICENSE for license details. + +package chisel.util + +import chisel._ + +/** A counter module + * @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) { + require(n >= 0) + val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) + /** Increment the counter, returning whether the counter currently is at the + * maximum and will wrap. The incremented value is registered and will be + * visible on the next cycle. + */ + def inc(): Bool = { + if (n > 1) { + val wrap = value === UInt(n-1) + value := value + UInt(1) + if (!isPow2(n)) { + when (wrap) { value := UInt(0) } + } + wrap + } else { + Bool(true) + } + } +} + +/** Counter Object + * Example Usage: + * {{{ val countOn = Bool(true) // increment counter every clock cycle + * val myCounter = Counter(countOn, n) + * when ( myCounter.value === UInt(3) ) { ... } }}}*/ +object Counter +{ + def apply(n: Int): Counter = new Counter(n) + def apply(cond: Bool, n: Int): (UInt, Bool) = { + val c = new Counter(n) + var wrap: Bool = null + when (cond) { wrap = c.inc() } + (c.value, cond && wrap) + } +} diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala new file mode 100644 index 00000000..89b0e39d --- /dev/null +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -0,0 +1,185 @@ +// See LICENSE for license details. + +/** Wrappers for ready-valid (Decoupled) interfaces and associated circuit generators using them. + */ + +package chisel.util + +import chisel._ + +/** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ +class DecoupledIO[+T <: Data](gen: T) extends Bundle +{ + val ready = Bool(INPUT) + val valid = Bool(OUTPUT) + val bits = gen.cloneType.asOutput + def fire(dummy: Int = 0): Bool = ready && valid + override def cloneType: this.type = new DecoupledIO(gen).asInstanceOf[this.type] +} + +/** Adds a ready-valid handshaking protocol to any interface. + * The standard used is that the consumer uses the flipped interface. + */ +object Decoupled { + def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) +} + +/** An I/O bundle for enqueuing data with valid/ready handshaking + * Initialization must be handled, if necessary, by the parent circuit + */ +class EnqIO[T <: Data](gen: T) extends DecoupledIO(gen) +{ + /** push dat onto the output bits of this interface to let the consumer know it has happened. + * @param dat the values to assign to bits. + * @return dat. + */ + def enq(dat: T): T = { valid := Bool(true); bits := dat; dat } + + /** Initialize this Bundle. Valid is set to false, and all bits are set to zero. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + valid := Bool(false) + for (io <- bits.flatten) + io := UInt(0) + } + override def cloneType: this.type = { new EnqIO(gen).asInstanceOf[this.type]; } +} + +/** An I/O bundle for dequeuing data with valid/ready handshaking. + * Initialization must be handled, if necessary, by the parent circuit + */ +class DeqIO[T <: Data](gen: T) extends DecoupledIO(gen) with Flipped +{ + /** Assert ready on this port and return the associated data bits. + * This is typically used when valid has been asserted by the producer side. + * @param b ignored + * @return the data for this device, + */ + def deq(b: Boolean = false): T = { ready := Bool(true); bits } + + /** Initialize this Bundle. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + ready := Bool(false) + } + override def cloneType: this.type = { new DeqIO(gen).asInstanceOf[this.type]; } +} + +/** An I/O bundle for dequeuing data with valid/ready handshaking */ +class DecoupledIOC[+T <: Data](gen: T) extends Bundle +{ + val ready = Bool(INPUT) + val valid = Bool(OUTPUT) + val bits = gen.cloneType.asOutput +} + +/** 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 +{ + /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ + val enq = Decoupled(gen.cloneType).flip() + /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ + val deq = Decoupled(gen.cloneType) + /** The current amount of data in the queue */ + val count = UInt(OUTPUT, log2Up(entries + 1)) +} + +/** A hardware module implementing a Queue + * @param gen The type of data to queue + * @param entries The max number of entries in the queue + * @param pipe True if a single entry queue can run at full throughput (like a pipeline). The ''ready'' signals are + * 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. + * + * Example usage: + * {{{ val q = new Queue(UInt(), 16) + * q.io.enq <> producer.io.out + * consumer.io.in <> q.io.deq }}} + */ +class Queue[T <: Data](gen: T, val entries: Int, + pipe: Boolean = false, + flow: Boolean = false, + override_reset: Option[Bool] = None) +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)) + + val io = new QueueIO(gen, entries) + + val ram = Mem(entries, gen) + val enq_ptr = Counter(entries) + val deq_ptr = Counter(entries) + val maybe_full = Reg(init=Bool(false)) + + val ptr_match = enq_ptr.value === deq_ptr.value + val empty = ptr_match && !maybe_full + val full = ptr_match && maybe_full + val do_enq = Wire(init=io.enq.fire()) + val do_deq = Wire(init=io.deq.fire()) + + when (do_enq) { + ram(enq_ptr.value) := io.enq.bits + enq_ptr.inc() + } + when (do_deq) { + deq_ptr.inc() + } + when (do_enq != do_deq) { + maybe_full := do_enq + } + + io.deq.valid := !empty + io.enq.ready := !full + io.deq.bits := ram(deq_ptr.value) + + if (flow) { + when (io.enq.valid) { io.deq.valid := Bool(true) } + when (empty) { + io.deq.bits := io.enq.bits + do_deq := Bool(false) + when (io.deq.ready) { do_enq := Bool(false) } + } + } + + if (pipe) { + when (io.deq.ready) { io.enq.ready := Bool(true) } + } + + val ptr_diff = enq_ptr.value - deq_ptr.value + if (isPow2(entries)) { + io.count := Cat(maybe_full && ptr_match, ptr_diff) + } else { + io.count := Mux(ptr_match, + Mux(maybe_full, + UInt(entries), UInt(0)), + Mux(deq_ptr.value > enq_ptr.value, + UInt(entries) + ptr_diff, ptr_diff)) + } +} + +/** Generic hardware queue. Required parameter entries controls + the depth of the queues. The width of the queue is determined + from the inputs. + + Example usage: + {{{ val q = Queue(Decoupled(UInt()), 16) + q.io.enq <> producer.io.out + consumer.io.in <> q.io.deq }}} + */ +object Queue +{ + def apply[T <: Data](enq: DecoupledIO[T], entries: Int = 2, pipe: Boolean = false): DecoupledIO[T] = { + val q = Module(new Queue(enq.bits.cloneType, entries, pipe)) + 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 + TransitName(q.io.deq, q) + } +} diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala new file mode 100644 index 00000000..8babcd23 --- /dev/null +++ b/src/main/scala/chisel3/util/Enum.scala @@ -0,0 +1,23 @@ +// See LICENSE for license details. + +/** Enum generators, allowing circuit constants to have more meaningful names. + */ + +package chisel.util + +import chisel._ + +object Enum { + /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ + private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] = + (0 until n).map(x => nodeType.fromInt(x, log2Up(n))) + + /** create n enum values of given type */ + def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList + + /** create enum values of given type and names */ + def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap + + /** create enum values of given type and names */ + def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap +} diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala new file mode 100644 index 00000000..846c0cbd --- /dev/null +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -0,0 +1,10 @@ +// See LICENSE for license details. + +package chisel.util + +import chisel._ + +object ImplicitConversions { + implicit def intToUInt(x: Int): UInt = UInt(x) + implicit def booleanToBool(x: Boolean): Bool = Bool(x) +} diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala new file mode 100644 index 00000000..f70630bf --- /dev/null +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -0,0 +1,24 @@ +// See LICENSE for license details. + +/** LFSRs in all shapes and sizes. + */ + +package chisel.util + +import chisel._ + +// scalastyle:off magic.number +/** linear feedback shift register + */ +object LFSR16 +{ + def apply(increment: Bool = Bool(true)): UInt = + { + val width = 16 + val lfsr = Reg(init=UInt(1, width)) + when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } + lfsr + } +} +// scalastyle:on magic.number + diff --git a/src/main/scala/chisel3/util/Lookup.scala b/src/main/scala/chisel3/util/Lookup.scala new file mode 100644 index 00000000..d32d9aec --- /dev/null +++ b/src/main/scala/chisel3/util/Lookup.scala @@ -0,0 +1,19 @@ +// See LICENSE for license details. + +package chisel.util + +import chisel._ + +object ListLookup { + def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = { + val map = mapping.map(m => (m._1 === addr, m._2)) + default.zipWithIndex map { case (d, i) => + map.foldRight(d)((m, n) => Mux(m._1, m._2(i), n)) + } + } +} + +object Lookup { + def apply[T <: Bits](addr: UInt, default: T, mapping: Seq[(BitPat, T)]): T = + ListLookup(addr, List(default), mapping.map(m => (m._1, List(m._2))).toArray).head +} diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala new file mode 100644 index 00000000..69464d15 --- /dev/null +++ b/src/main/scala/chisel3/util/Math.scala @@ -0,0 +1,44 @@ +// See LICENSE for license details. + +/** Scala-land math helper functions, like logs. + */ + +package chisel.util + +import chisel._ + +/** Compute the log2 rounded up with min value of 1 */ +object log2Up { + def apply(in: BigInt): Int = { + require(in >= 0) + 1 max (in-1).bitLength + } + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded up */ +object log2Ceil { + def apply(in: BigInt): Int = { + require(in > 0) + (in-1).bitLength + } + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded down with min value of 1 */ +object log2Down { + def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1) + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded down */ +object log2Floor { + def apply(in: BigInt): Int = log2Ceil(in) - (if (isPow2(in)) 0 else 1) + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Check if an Integer is a power of 2 */ +object isPow2 { + def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) + def apply(in: Int): Boolean = apply(BigInt(in)) +} diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala new file mode 100644 index 00000000..6f074a7e --- /dev/null +++ b/src/main/scala/chisel3/util/Mux.scala @@ -0,0 +1,64 @@ +// See LICENSE for license details. + +/** Mux circuit generators. + */ + +package chisel.util + +import chisel._ +import chisel.core.SeqUtils + +/** Builds a Mux tree out of the input signal vector using a one hot encoded + select signal. Returns the output of the Mux tree. + */ +object Mux1H +{ + def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = + apply(sel zip in) + def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in) + def apply[T <: Data](sel: UInt, in: Seq[T]): T = + apply((0 until in.size).map(sel(_)), in) + def apply(sel: UInt, in: UInt): Bool = (sel & in).orR +} + +/** Builds a Mux tree under the assumption that multiple select signals + can be enabled. Priority is given to the first select signal. + + Returns the output of the Mux tree. + */ +object PriorityMux +{ + def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in) + def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) + def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) +} + +/** MuxLookup creates a cascade of n Muxs to search for a key value */ +object MuxLookup { + /** @param key a key to search for + * @param default a default value if nothing is found + * @param mapping a sequence to search of keys and values + * @return the value found or the default if not + */ + def apply[S <: UInt, T <: Bits] (key: S, default: T, mapping: Seq[(S, T)]): T = { + var res = default + for ((k, v) <- mapping.reverse) + res = Mux(k === key, v, res) + res + } + +} + +/** MuxCase returns the first value that is enabled in a map of values */ +object MuxCase { + /** @param default the default value if none are enabled + * @param mapping a set of data values with associated enables + * @return the first value in mapping that is enabled */ + def apply[T <: Bits] (default: T, mapping: Seq[(Bool, T)]): T = { + var res = default + for ((t, v) <- mapping.reverse){ + res = Mux(t, v, res) + } + res + } +} diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala new file mode 100644 index 00000000..ef21c65d --- /dev/null +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -0,0 +1,64 @@ +// See LICENSE for license details. + +/** Circuit generators for working with one-hot representations. + */ + +package chisel.util + +import chisel._ + +/** Converts from One Hot Encoding to a UInt indicating which bit is active + * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ +object OHToUInt { + def apply(in: Seq[Bool]): UInt = apply(Vec(in)) + def apply(in: Vec[Bool]): UInt = apply(in.toBits, in.size) + def apply(in: Bits): UInt = apply(in, in.getWidth) + + def apply(in: Bits, width: Int): UInt = { + if (width <= 2) { + Log2(in, width) + } else { + val mid = 1 << (log2Up(width)-1) + val hi = in(width-1, mid) + val lo = in(mid-1, 0) + Cat(hi.orR, apply(hi | lo, mid)) + } + } +} + +/** @return the bit position of the trailing 1 in the input vector + * with the assumption that multiple bits of the input bit vector can be set + * @example {{{ data_out := PriorityEncoder(data_in) }}} + */ +object PriorityEncoder { + def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) + def apply(in: Bits): UInt = apply(in.toBools) +} + +/** Returns the one hot encoding of the input UInt. + */ +object UIntToOH +{ + def apply(in: UInt, width: Int = -1): UInt = + if (width == -1) { + UInt(1) << in + } else { + (UInt(1) << in(log2Up(width)-1,0))(width-1,0) + } +} + +/** Returns a bit vector in which only the least-significant 1 bit in + the input vector, if any, is set. + */ +object PriorityEncoderOH +{ + private def encode(in: Seq[Bool]): UInt = { + val outs = Seq.tabulate(in.size)(i => UInt(BigInt(1) << i, in.size)) + PriorityMux(in :+ Bool(true), outs :+ UInt(0, in.size)) + } + def apply(in: Seq[Bool]): Seq[Bool] = { + val enc = encode(in) + Seq.tabulate(in.size)(enc(_)) + } + def apply(in: Bits): UInt = encode((0 until in.getWidth).map(i => in(i))) +} diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala new file mode 100644 index 00000000..1b40646d --- /dev/null +++ b/src/main/scala/chisel3/util/Reg.scala @@ -0,0 +1,57 @@ +// See LICENSE for license details. + +/** Variations and helpers for registers. + */ + +package chisel.util + +import chisel._ + +object RegNext { + + def apply[T <: Data](next: T): T = Reg[T](null.asInstanceOf[T], next, null.asInstanceOf[T]) + + def apply[T <: Data](next: T, init: T): T = Reg[T](null.asInstanceOf[T], next, init) + +} + +object RegInit { + + def apply[T <: Data](init: T): T = Reg[T](null.asInstanceOf[T], null.asInstanceOf[T], init) + +} + +/** A register with an Enable signal */ +object RegEnable +{ + def apply[T <: Data](updateData: T, enable: Bool): T = { + val r = Reg(updateData) + when (enable) { r := updateData } + r + } + def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = { + val r = RegInit(resetData) + when (enable) { r := updateData } + r + } +} + +/** Returns the n-cycle delayed version of the input signal. + */ +object ShiftRegister +{ + /** @param in input to delay + * @param n number of cycles to delay + * @param en enable the shift */ + def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = + { + // The order of tests reflects the expected use cases. + if (n == 1) { + RegEnable(in, en) + } else if (n != 0) { + RegNext(apply(in, n-1, en)) + } else { + in + } + } +} diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala new file mode 100644 index 00000000..04e1995b --- /dev/null +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -0,0 +1,22 @@ +package chisel.util + +import chisel._ +import internal.HasId + +object TransitName { + // The purpose of this is to allow a library to 'move' a name call to a more + // appropriate place. + // For example, a library factory function may create a module and return + // the io. The only user-exposed field is that given IO, which can't use + // any name supplied by the user. This can add a hook so that the supplied + // name then names the Module. + // See Queue companion object for working example + def apply[T<:HasId](from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name)}) + from + } + def withSuffix[T<:HasId](suffix: String)(from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name+suffix)}) + from + } +} diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala new file mode 100644 index 00000000..56ac9abb --- /dev/null +++ b/src/main/scala/chisel3/util/Valid.scala @@ -0,0 +1,61 @@ +// See LICENSE for license details. + +/** Wrappers for valid interfaces and associated circuit generators using them. + */ + +package chisel.util + +import chisel._ + +/** An I/O Bundle containing data and a signal determining if it is valid */ +class ValidIO[+T <: Data](gen2: T) extends Bundle +{ + val valid = Bool(OUTPUT) + val bits = gen2.cloneType.asOutput + def fire(dummy: Int = 0): Bool = valid + override def cloneType: this.type = new ValidIO(gen2).asInstanceOf[this.type] +} + +/** Adds a valid protocol to any interface. The standard used is + that the consumer uses the flipped interface. +*/ +object Valid { + def apply[T <: Data](gen: T): ValidIO[T] = new ValidIO(gen) +} + +/** 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. + + 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): ValidIO[T] = { + if (latency == 0) { + val out = Wire(Valid(enqBits)) + out.valid <> enqValid + out.bits <> enqBits + out + } else { + val v = Reg(Bool(), next=enqValid, init=Bool(false)) + val b = RegEnable(enqBits, enqValid) + apply(v, b, latency-1) + } + } + def apply[T <: Data](enqValid: Bool, enqBits: T): ValidIO[T] = apply(enqValid, enqBits, 1) + def apply[T <: Data](enq: ValidIO[T], latency: Int = 1): ValidIO[T] = apply(enq.valid, enq.bits, latency) +} + +class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module +{ + val io = new Bundle { + val enq = Valid(gen).flip + val deq = Valid(gen) + } + + io.deq <> Pipe(io.enq, latency) +} -- cgit v1.2.3 From 3026dd214f3db3308eaf8f876d0fc03f75c577d3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 20 Jun 2016 11:38:26 -0700 Subject: Rename "package", "import", and explicit references to "chisel3". --- src/main/scala/chisel3/util/Arbiter.scala | 4 ++-- src/main/scala/chisel3/util/BitPat.scala | 6 +++--- src/main/scala/chisel3/util/Bitwise.scala | 6 +++--- src/main/scala/chisel3/util/Cat.scala | 6 +++--- src/main/scala/chisel3/util/CircuitMath.scala | 4 ++-- src/main/scala/chisel3/util/Conditional.scala | 6 +++--- src/main/scala/chisel3/util/Counter.scala | 4 ++-- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- src/main/scala/chisel3/util/Enum.scala | 4 ++-- src/main/scala/chisel3/util/ImplicitConversions.scala | 4 ++-- src/main/scala/chisel3/util/LFSR.scala | 4 ++-- src/main/scala/chisel3/util/Lookup.scala | 4 ++-- src/main/scala/chisel3/util/Math.scala | 4 ++-- src/main/scala/chisel3/util/Mux.scala | 6 +++--- src/main/scala/chisel3/util/OneHot.scala | 4 ++-- src/main/scala/chisel3/util/Reg.scala | 4 ++-- src/main/scala/chisel3/util/TransitName.scala | 4 ++-- src/main/scala/chisel3/util/Valid.scala | 4 ++-- 18 files changed, 41 insertions(+), 41 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 3723f2a9..eb541977 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -3,9 +3,9 @@ /** Arbiters in all shapes and sizes. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 13bbe1b0..9eb5cf67 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -1,11 +1,11 @@ // See LICENSE for license details. -package chisel.util +package chisel3.util import scala.language.experimental.macros -import chisel._ -import chisel.internal.sourceinfo.{SourceInfo, SourceInfoTransform} +import chisel3._ +import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} object BitPat { /** Parses a bit pattern string into (bits, mask, width). diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index d7d62ea3..ab1ff550 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -3,10 +3,10 @@ /** Miscellaneous circuit generators operating on bits. */ -package chisel.util +package chisel3.util -import chisel._ -import chisel.core.SeqUtils +import chisel3._ +import chisel3.core.SeqUtils object FillInterleaved { diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala index b47da706..469bf9ab 100644 --- a/src/main/scala/chisel3/util/Cat.scala +++ b/src/main/scala/chisel3/util/Cat.scala @@ -1,9 +1,9 @@ // See LICENSE for license details. -package chisel.util +package chisel3.util -import chisel._ -import chisel.core.SeqUtils +import chisel3._ +import chisel3.core.SeqUtils object Cat { /** Combine data elements together diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index c3b94fdb..1174c71c 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -3,9 +3,9 @@ /** Circuit-land math operations. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** Compute Log2 with truncation of a UInt in hardware using a Mux Tree * An alternative interpretation is it computes the minimum number of bits needed to represent x diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 01c12799..6218feb0 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -3,14 +3,14 @@ /** Conditional blocks. */ -package chisel.util +package chisel3.util import scala.language.reflectiveCalls import scala.language.experimental.macros import scala.reflect.runtime.universe._ import scala.reflect.macros.blackbox._ -import chisel._ +import chisel3._ /** This is identical to [[Chisel.when when]] with the condition inverted */ object unless { // scalastyle:ignore object.name @@ -63,7 +63,7 @@ object switch { // scalastyle:ignore object.name def extractIsStatement(tree: Tree): List[c.universe.Tree] = tree match { // TODO: remove when Chisel compatibility package is removed case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") - case q"chisel.util.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + case q"chisel3.util.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") } val q"..$body" = x diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 1c0b0203..40615769 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -1,8 +1,8 @@ // See LICENSE for license details. -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** A counter module * @param n number of counts before the counter resets (or one more than the diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 89b0e39d..f37a5c31 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -3,9 +3,9 @@ /** Wrappers for ready-valid (Decoupled) interfaces and associated circuit generators using them. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ class DecoupledIO[+T <: Data](gen: T) extends Bundle diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 8babcd23..4ecc243b 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -3,9 +3,9 @@ /** Enum generators, allowing circuit constants to have more meaningful names. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ object Enum { /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 846c0cbd..4d816a19 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -1,8 +1,8 @@ // See LICENSE for license details. -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ object ImplicitConversions { implicit def intToUInt(x: Int): UInt = UInt(x) diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index f70630bf..a30c276f 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -3,9 +3,9 @@ /** LFSRs in all shapes and sizes. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ // scalastyle:off magic.number /** linear feedback shift register diff --git a/src/main/scala/chisel3/util/Lookup.scala b/src/main/scala/chisel3/util/Lookup.scala index d32d9aec..9e909c0c 100644 --- a/src/main/scala/chisel3/util/Lookup.scala +++ b/src/main/scala/chisel3/util/Lookup.scala @@ -1,8 +1,8 @@ // See LICENSE for license details. -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ object ListLookup { def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = { diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala index 69464d15..73665f0f 100644 --- a/src/main/scala/chisel3/util/Math.scala +++ b/src/main/scala/chisel3/util/Math.scala @@ -3,9 +3,9 @@ /** Scala-land math helper functions, like logs. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** Compute the log2 rounded up with min value of 1 */ object log2Up { diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala index 6f074a7e..07a34f9b 100644 --- a/src/main/scala/chisel3/util/Mux.scala +++ b/src/main/scala/chisel3/util/Mux.scala @@ -3,10 +3,10 @@ /** Mux circuit generators. */ -package chisel.util +package chisel3.util -import chisel._ -import chisel.core.SeqUtils +import chisel3._ +import chisel3.core.SeqUtils /** Builds a Mux tree out of the input signal vector using a one hot encoded select signal. Returns the output of the Mux tree. diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index ef21c65d..820c72d6 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -3,9 +3,9 @@ /** Circuit generators for working with one-hot representations. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** Converts from One Hot Encoding to a UInt indicating which bit is active * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 1b40646d..81de4754 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -3,9 +3,9 @@ /** Variations and helpers for registers. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ object RegNext { diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala index 04e1995b..f36f926f 100644 --- a/src/main/scala/chisel3/util/TransitName.scala +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -1,6 +1,6 @@ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ import internal.HasId object TransitName { diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 56ac9abb..78187ff6 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -3,9 +3,9 @@ /** Wrappers for valid interfaces and associated circuit generators using them. */ -package chisel.util +package chisel3.util -import chisel._ +import chisel3._ /** An I/O Bundle containing data and a signal determining if it is valid */ class ValidIO[+T <: Data](gen2: T) extends Bundle -- cgit v1.2.3 From fb39f7dc372b5836f02d8d7964f5fcc6a38f8747 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 7 Jul 2016 00:11:15 -0700 Subject: Avoid needlessly creating Vecs --- src/main/scala/chisel3/util/Bitwise.scala | 2 +- src/main/scala/chisel3/util/OneHot.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index ab1ff550..7f295200 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -11,7 +11,7 @@ import chisel3.core.SeqUtils object FillInterleaved { def apply(n: Int, in: UInt): UInt = apply(n, in.toBools) - def apply(n: Int, in: Seq[Bool]): UInt = Vec(in.map(Fill(n, _))).toBits + def apply(n: Int, in: Seq[Bool]): UInt = Cat(in.map(Fill(n, _)).reverse) } /** Returns the number of bits set (i.e value is 1) in the input signal. diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 820c72d6..abede61e 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -10,7 +10,7 @@ import chisel3._ /** Converts from One Hot Encoding to a UInt indicating which bit is active * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ object OHToUInt { - def apply(in: Seq[Bool]): UInt = apply(Vec(in)) + def apply(in: Seq[Bool]): UInt = apply(Cat(in.reverse), in.size) def apply(in: Vec[Bool]): UInt = apply(in.toBits, in.size) def apply(in: Bits): UInt = apply(in, in.getWidth) -- cgit v1.2.3 From bae5cbbbf64782ffe7a5a06981d94655bfc76089 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Wed, 6 Jul 2016 23:01:42 -0700 Subject: Correct erroneous Log2 documentation --- src/main/scala/chisel3/util/CircuitMath.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 1174c71c..b5be03bf 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -7,11 +7,11 @@ package chisel3.util import chisel3._ -/** Compute Log2 with truncation of a UInt in hardware using a Mux Tree - * An alternative interpretation is it computes the minimum number of bits needed to represent x +/** Compute the base-2 integer logarithm of a UInt * @example * {{{ data_out := Log2(data_in) }}} - * @note Truncation is used so Log2(UInt(12412)) = 13*/ + * @note The result is truncated, so e.g. Log2(UInt(13)) = 3 + */ object Log2 { /** Compute the Log2 on the least significant n bits of x */ def apply(x: Bits, width: Int): UInt = { -- cgit v1.2.3 From a49e27d1247597de5997f0fe6f3d2ac594ec2e6b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 7 Jul 2016 00:37:34 -0700 Subject: Improve Fill code generation --- src/main/scala/chisel3/util/Bitwise.scala | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index 7f295200..3134d043 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -29,22 +29,17 @@ object Fill { n match { case 0 => UInt(width=0) case 1 => x - case y if n > 1 => + case _ if x.width.known && x.getWidth == 1 => + Mux(x.toBool, UInt((BigInt(1) << n) - 1, n), UInt(0, n)) + case _ if n > 1 => val p2 = Array.ofDim[UInt](log2Up(n + 1)) p2(0) = x for (i <- 1 until p2.length) p2(i) = Cat(p2(i-1), p2(i-1)) - Cat((0 until log2Up(y + 1)).filter(i => (y & (1 << i)) != 0).map(p2(_))) + Cat((0 until log2Up(n + 1)).filter(i => (n & (1 << i)) != 0).map(p2(_))) case _ => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.") } } - /** Fan out x n times */ - def apply(n: Int, x: Bool): UInt = - if (n > 1) { - UInt(0,n) - x - } else { - apply(n, x: UInt) - } } /** Litte/big bit endian convertion: reverse the order of the bits in a UInt. -- cgit v1.2.3 From c90be4ea06faf9a39c85f38e932d29fe63eb4b37 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 7 Jul 2016 15:41:10 -0700 Subject: Improve QoR for Log2 For reasonable circuit delay, need to divide & conquer. --- src/main/scala/chisel3/util/CircuitMath.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index b5be03bf..a64447d9 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -19,10 +19,18 @@ object Log2 { UInt(0) } else if (width == 2) { x(1) - } else { + } else if (width <= divideAndConquerThreshold) { Mux(x(width-1), UInt(width-1), apply(x, width-1)) + } else { + val mid = 1 << (log2Ceil(width) - 1) + val hi = x(width-1, mid) + val lo = x(mid-1, 0) + val useHi = hi.orR + Cat(useHi, Mux(useHi, Log2(hi, width - mid), Log2(lo, mid))) } } def apply(x: Bits): UInt = apply(x, x.getWidth) + + private def divideAndConquerThreshold = 4 } -- cgit v1.2.3 From bb5467fc67d3b8fc6cc2a15f6e681dc45f7cb029 Mon Sep 17 00:00:00 2001 From: Donggyu Date: Mon, 11 Jul 2016 15:17:59 -0700 Subject: bitpat should keep the width of uint (#232) --- src/main/scala/chisel3/util/BitPat.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 9eb5cf67..d476f957 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -68,7 +68,8 @@ object BitPat { */ def apply(x: UInt): BitPat = { require(x.isLit) - BitPat("b" + x.litValue.toString(2)) + val len = if (x.width.known) x.getWidth else 0 + apply("b" + x.litValue.toString(2).reverse.padTo(len, "0").reverse.mkString) } } @@ -83,7 +84,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg def != (that: UInt): Bool = macro SourceInfoTransform.thatArg - def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = UInt(value) === (that & UInt(mask)) + def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = UInt(value, width) === (that & UInt(mask)) def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that } -- cgit v1.2.3 From c5f9ea3133ef363ff8944e17d94fea79767b6bed Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 6 Jul 2016 10:01:23 -0700 Subject: Rename "Chisel" to "chisel3" (only git mv). --- src/main/scala/chisel3/util/Arbiter.scala | 117 +++++++++++++ src/main/scala/chisel3/util/BitPat.scala | 88 ++++++++++ src/main/scala/chisel3/util/Bitwise.scala | 71 ++++++++ src/main/scala/chisel3/util/Cat.scala | 18 ++ src/main/scala/chisel3/util/CircuitMath.scala | 26 +++ src/main/scala/chisel3/util/Conditional.scala | 69 ++++++++ src/main/scala/chisel3/util/Counter.scala | 44 +++++ src/main/scala/chisel3/util/Decoupled.scala | 183 +++++++++++++++++++++ src/main/scala/chisel3/util/Enum.scala | 21 +++ .../scala/chisel3/util/ImplicitConversions.scala | 8 + src/main/scala/chisel3/util/LFSR.scala | 22 +++ src/main/scala/chisel3/util/Lookup.scala | 17 ++ src/main/scala/chisel3/util/Math.scala | 42 +++++ src/main/scala/chisel3/util/Mux.scala | 61 +++++++ src/main/scala/chisel3/util/OneHot.scala | 62 +++++++ src/main/scala/chisel3/util/Reg.scala | 55 +++++++ src/main/scala/chisel3/util/TransitName.scala | 21 +++ src/main/scala/chisel3/util/Valid.scala | 59 +++++++ 18 files changed, 984 insertions(+) create mode 100644 src/main/scala/chisel3/util/Arbiter.scala create mode 100644 src/main/scala/chisel3/util/BitPat.scala create mode 100644 src/main/scala/chisel3/util/Bitwise.scala create mode 100644 src/main/scala/chisel3/util/Cat.scala create mode 100644 src/main/scala/chisel3/util/CircuitMath.scala create mode 100644 src/main/scala/chisel3/util/Conditional.scala create mode 100644 src/main/scala/chisel3/util/Counter.scala create mode 100644 src/main/scala/chisel3/util/Decoupled.scala create mode 100644 src/main/scala/chisel3/util/Enum.scala create mode 100644 src/main/scala/chisel3/util/ImplicitConversions.scala create mode 100644 src/main/scala/chisel3/util/LFSR.scala create mode 100644 src/main/scala/chisel3/util/Lookup.scala create mode 100644 src/main/scala/chisel3/util/Math.scala create mode 100644 src/main/scala/chisel3/util/Mux.scala create mode 100644 src/main/scala/chisel3/util/OneHot.scala create mode 100644 src/main/scala/chisel3/util/Reg.scala create mode 100644 src/main/scala/chisel3/util/TransitName.scala create mode 100644 src/main/scala/chisel3/util/Valid.scala (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala new file mode 100644 index 00000000..16ae9be5 --- /dev/null +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -0,0 +1,117 @@ +// See LICENSE for license details. + +/** Arbiters in all shapes and sizes. + */ + +package Chisel + +/** An I/O bundle for the Arbiter */ +class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { + val in = Vec(n, Decoupled(gen)).flip + val out = Decoupled(gen) + val chosen = UInt(OUTPUT, log2Up(n)) +} + +/** Arbiter Control determining which producer has access */ +private object ArbiterCtrl +{ + def apply(request: Seq[Bool]): Seq[Bool] = request.length match { + case 0 => Seq() + case 1 => Seq(Bool(true)) + case _ => Bool(true) +: request.tail.init.scanLeft(request.head)(_ || _).map(!_) + } +} + +abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool]) extends Module { + def grant: Seq[Bool] + def choice: UInt + val io = new ArbiterIO(gen, n) + + io.chosen := choice + io.out.valid := io.in(io.chosen).valid + io.out.bits := io.in(io.chosen).bits + + if (count > 1) { + val lockCount = Counter(count) + val lockIdx = Reg(UInt()) + val locked = lockCount.value =/= UInt(0) + val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(Bool(true)) + + when (io.out.fire() && wantsLock) { + lockIdx := io.chosen + lockCount.inc() + } + + when (locked) { io.chosen := lockIdx } + for ((in, (g, i)) <- io.in zip grant.zipWithIndex) + in.ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready + } else { + for ((in, g) <- io.in zip grant) + in.ready := g && io.out.ready + } +} + +class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) + extends LockingArbiterLike[T](gen, n, count, needsLock) { + lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) + lazy val grantMask = (0 until n).map(UInt(_) > lastGrant) + lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } + + override def grant: Seq[Bool] = { + val ctrl = ArbiterCtrl((0 until n).map(i => validMask(i)) ++ io.in.map(_.valid)) + (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) + } + + override lazy val choice = Wire(init=UInt(n-1)) + for (i <- n-2 to 0 by -1) + when (io.in(i).valid) { choice := UInt(i) } + for (i <- n-1 to 1 by -1) + when (validMask(i)) { choice := UInt(i) } +} + +class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) + extends LockingArbiterLike[T](gen, n, count, needsLock) { + def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) + + override lazy val choice = Wire(init=UInt(n-1)) + for (i <- n-2 to 0 by -1) + when (io.in(i).valid) { choice := UInt(i) } +} + +/** Hardware module that is used to sequence n producers into 1 consumer. + Producers are chosen in round robin order. + + Example usage: + val arb = new RRArbiter(2, UInt()) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) + +/** Hardware module that is used to sequence n producers into 1 consumer. + Priority is given to lower producer + + Example usage: + val arb = Module(new Arbiter(2, UInt())) + arb.io.in(0) <> producer0.io.out + arb.io.in(1) <> producer1.io.out + consumer.io.in <> arb.io.out + */ +class Arbiter[T <: Data](gen: T, n: Int) extends Module { + val io = new ArbiterIO(gen, n) + + io.chosen := UInt(n-1) + io.out.bits := io.in(n-1).bits + for (i <- n-2 to 0 by -1) { + when (io.in(i).valid) { + io.chosen := UInt(i) + io.out.bits := io.in(i).bits + } + } + + val grant = ArbiterCtrl(io.in.map(_.valid)) + for ((in, g) <- io.in zip grant) + in.ready := g && io.out.ready + io.out.valid := !grant.last || io.in.last.valid +} diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala new file mode 100644 index 00000000..96206f63 --- /dev/null +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -0,0 +1,88 @@ +// See LICENSE for license details. + +package Chisel + +import scala.language.experimental.macros + +import Chisel.internal.sourceinfo.{SourceInfo, SourceInfoTransform} + +object BitPat { + /** Parses a bit pattern string into (bits, mask, width). + * + * @return bits the literal value, with don't cares being 0 + * @return mask the mask bits, with don't cares being 0 and cares being 1 + * @return width the number of bits in the literal, including values and + * don't cares. + */ + private def parse(x: String): (BigInt, BigInt, Int) = { + // Notes: + // While Verilog Xs also handle octal and hex cases, there isn't a + // compelling argument and no one has asked for it. + // If ? parsing is to be exposed, the return API needs further scrutiny + // (especially with things like mask polarity). + require(x.head == 'b', "BitPats must be in binary and be prefixed with 'b'") + var bits = BigInt(0) + var mask = BigInt(0) + for (d <- x.tail) { + if (d != '_') { + require("01?".contains(d), "Literal: " + x + " contains illegal character: " + d) + mask = (mask << 1) + (if (d == '?') 0 else 1) + bits = (bits << 1) + (if (d == '1') 1 else 0) + } + } + (bits, mask, x.length - 1) + } + + /** Creates a [[BitPat]] literal from a string. + * + * @param n the literal value as a string, in binary, prefixed with 'b' + * @note legal characters are '0', '1', and '?', as well as '_' as white + * space (which are ignored) + */ + def apply(n: String): BitPat = { + val (bits, mask, width) = parse(n) + new BitPat(bits, mask, width) + } + + /** Creates a [[BitPat]] of all don't cares of the specified bitwidth. */ + def dontCare(width: Int): BitPat = BitPat("b" + ("?" * width)) + + @deprecated("Use BitPat.dontCare", "chisel3") + def DC(width: Int): BitPat = dontCare(width) // scalastyle:ignore method.name + + /** Allows BitPats to be used where a UInt is expected. + * + * @note the BitPat must not have don't care bits (will error out otherwise) + */ + def bitPatToUInt(x: BitPat): UInt = { + require(x.mask == (BigInt(1) << x.getWidth) - 1) + UInt(x.value, x.getWidth) + } + + /** Allows UInts to be used where a BitPat is expected, useful for when an + * interface is defined with BitPats but not all cases need the partial + * matching capability. + * + * @note the UInt must be a literal + */ + def apply(x: UInt): BitPat = { + require(x.isLit) + BitPat("b" + x.litValue.toString(2)) + } +} + +// TODO: Break out of Core? (this doesn't involve FIRRTL generation) +/** Bit patterns are literals with masks, used to represent values with don't + * cares. Equality comparisons will ignore don't care bits (for example, + * BitPat(0b10?1) === UInt(0b1001) and UInt(0b1011)). + */ +sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { + def getWidth: Int = width + def === (that: UInt): Bool = macro SourceInfoTransform.thatArg + def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg + def != (that: UInt): Bool = macro SourceInfoTransform.thatArg + + def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = UInt(value) === (that & UInt(mask)) + def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) + def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that +} diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala new file mode 100644 index 00000000..239a295e --- /dev/null +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -0,0 +1,71 @@ +// See LICENSE for license details. + +/** Miscellaneous circuit generators operating on bits. + */ + +package Chisel + +object FillInterleaved +{ + def apply(n: Int, in: UInt): UInt = apply(n, in.toBools) + def apply(n: Int, in: Seq[Bool]): UInt = Vec(in.map(Fill(n, _))).toBits +} + +/** Returns the number of bits set (i.e value is 1) in the input signal. + */ +object PopCount +{ + def apply(in: Iterable[Bool]): UInt = SeqUtils.count(in.toSeq) + def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_))) +} + +/** Fill fans out a UInt to multiple copies */ +object Fill { + /** Fan out x n times */ + def apply(n: Int, x: UInt): UInt = { + n match { + case 0 => UInt(width=0) + case 1 => x + case y if n > 1 => + val p2 = Array.ofDim[UInt](log2Up(n + 1)) + p2(0) = x + for (i <- 1 until p2.length) + p2(i) = Cat(p2(i-1), p2(i-1)) + Cat((0 until log2Up(y + 1)).filter(i => (y & (1 << i)) != 0).map(p2(_))) + case _ => throw new IllegalArgumentException(s"n (=$n) must be nonnegative integer.") + } + } + /** Fan out x n times */ + def apply(n: Int, x: Bool): UInt = + if (n > 1) { + UInt(0,n) - x + } else { + apply(n, x: UInt) + } +} + +/** Litte/big bit endian convertion: reverse the order of the bits in a UInt. +*/ +object Reverse +{ + private def doit(in: UInt, length: Int): UInt = { + if (length == 1) { + in + } else if (isPow2(length) && length >= 8 && length <= 64) { + // This esoterica improves simulation performance + var res = in + var shift = length >> 1 + var mask = UInt((BigInt(1) << length) - 1, length) + do { + mask = mask ^ (mask(length-shift-1,0) << shift) + res = ((res >> shift) & mask) | ((res(length-shift-1,0) << shift) & ~mask) + shift = shift >> 1 + } while (shift > 0) + res + } else { + val half = (1 << log2Up(length))/2 + Cat(doit(in(half-1,0), half), doit(in(length-1,half), length-half)) + } + } + def apply(in: UInt): UInt = doit(in, in.getWidth) +} diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala new file mode 100644 index 00000000..dd706e62 --- /dev/null +++ b/src/main/scala/chisel3/util/Cat.scala @@ -0,0 +1,18 @@ +// See LICENSE for license details. + +package Chisel + +object Cat { + /** Combine data elements together + * @param a Data to combine with + * @param r any number of other Data elements to be combined in order + * @return A UInt which is all of the bits combined together + */ + def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList) + + /** Combine data elements together + * @param r any number of other Data elements to be combined in order + * @return A UInt which is all of the bits combined together + */ + def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse) +} diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala new file mode 100644 index 00000000..06cab903 --- /dev/null +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -0,0 +1,26 @@ +// See LICENSE for license details. + +/** Circuit-land math operations. + */ + +package Chisel + +/** Compute Log2 with truncation of a UInt in hardware using a Mux Tree + * An alternative interpretation is it computes the minimum number of bits needed to represent x + * @example + * {{{ data_out := Log2(data_in) }}} + * @note Truncation is used so Log2(UInt(12412)) = 13*/ +object Log2 { + /** Compute the Log2 on the least significant n bits of x */ + def apply(x: Bits, width: Int): UInt = { + if (width < 2) { + UInt(0) + } else if (width == 2) { + x(1) + } else { + Mux(x(width-1), UInt(width-1), apply(x, width-1)) + } + } + + def apply(x: Bits): UInt = apply(x, x.getWidth) +} diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala new file mode 100644 index 00000000..9cab25ef --- /dev/null +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -0,0 +1,69 @@ +// See LICENSE for license details. + +/** Conditional blocks. + */ + +package Chisel + +import scala.language.reflectiveCalls +import scala.language.experimental.macros +import scala.reflect.runtime.universe._ +import scala.reflect.macros.blackbox._ + +/** This is identical to [[Chisel.when when]] with the condition inverted */ +object unless { // scalastyle:ignore object.name + def apply(c: Bool)(block: => Unit) { + when (!c) { block } + } +} + +class SwitchContext[T <: Bits](cond: T) { + def is(v: Iterable[T])(block: => Unit) { + if (!v.isEmpty) when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { block } + } + def is(v: T)(block: => Unit) { is(Seq(v))(block) } + def is(v: T, vr: T*)(block: => Unit) { is(v :: vr.toList)(block) } +} + +/** An object for separate cases in [[Chisel.switch switch]] + * It is equivalent to a [[Chisel.when$ when]] block comparing to the condition + * Use outside of a switch statement is illegal */ +object is { // scalastyle:ignore object.name + // Begin deprecation of non-type-parameterized is statements. + def apply(v: Iterable[Bits])(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } + + def apply(v: Bits)(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } + + def apply(v: Bits, vr: Bits*)(block: => Unit) { + require(false, "The 'is' keyword may not be used outside of a switch.") + } +} + +/** Conditional logic to form a switch block + * @example + * {{{ ... // default values here + * switch ( myState ) { + * is( state1 ) { + * ... // some logic here + * } + * is( state2 ) { + * ... // some logic here + * } + * } }}}*/ +object switch { // scalastyle:ignore object.name + def apply[T <: Bits](cond: T)(x: => Unit): Unit = macro impl + def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._ + val sc = c.universe.internal.reificationSupport.freshTermName("sc") + def extractIsStatement(tree: Tree): List[c.universe.Tree] = tree match { + case q"Chisel.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") + } + val q"..$body" = x + val ises = body.flatMap(extractIsStatement(_)) + q"""{ val $sc = new SwitchContext($cond); ..$ises }""" + } +} diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala new file mode 100644 index 00000000..872e830a --- /dev/null +++ b/src/main/scala/chisel3/util/Counter.scala @@ -0,0 +1,44 @@ +// See LICENSE for license details. + +package Chisel + +/** A counter module + * @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) { + require(n >= 0) + val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) + /** Increment the counter, returning whether the counter currently is at the + * maximum and will wrap. The incremented value is registered and will be + * visible on the next cycle. + */ + def inc(): Bool = { + if (n > 1) { + val wrap = value === UInt(n-1) + value := value + UInt(1) + if (!isPow2(n)) { + when (wrap) { value := UInt(0) } + } + wrap + } else { + Bool(true) + } + } +} + +/** Counter Object + * Example Usage: + * {{{ val countOn = Bool(true) // increment counter every clock cycle + * val myCounter = Counter(countOn, n) + * when ( myCounter.value === UInt(3) ) { ... } }}}*/ +object Counter +{ + def apply(n: Int): Counter = new Counter(n) + def apply(cond: Bool, n: Int): (UInt, Bool) = { + val c = new Counter(n) + var wrap: Bool = null + when (cond) { wrap = c.inc() } + (c.value, cond && wrap) + } +} diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala new file mode 100644 index 00000000..8e045855 --- /dev/null +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -0,0 +1,183 @@ +// See LICENSE for license details. + +/** Wrappers for ready-valid (Decoupled) interfaces and associated circuit generators using them. + */ + +package Chisel + +/** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ +class DecoupledIO[+T <: Data](gen: T) extends Bundle +{ + val ready = Bool(INPUT) + val valid = Bool(OUTPUT) + val bits = gen.cloneType.asOutput + def fire(dummy: Int = 0): Bool = ready && valid + override def cloneType: this.type = new DecoupledIO(gen).asInstanceOf[this.type] +} + +/** Adds a ready-valid handshaking protocol to any interface. + * The standard used is that the consumer uses the flipped interface. + */ +object Decoupled { + def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) +} + +/** An I/O bundle for enqueuing data with valid/ready handshaking + * Initialization must be handled, if necessary, by the parent circuit + */ +class EnqIO[T <: Data](gen: T) extends DecoupledIO(gen) +{ + /** push dat onto the output bits of this interface to let the consumer know it has happened. + * @param dat the values to assign to bits. + * @return dat. + */ + def enq(dat: T): T = { valid := Bool(true); bits := dat; dat } + + /** Initialize this Bundle. Valid is set to false, and all bits are set to zero. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + valid := Bool(false) + for (io <- bits.flatten) + io := UInt(0) + } + override def cloneType: this.type = { new EnqIO(gen).asInstanceOf[this.type]; } +} + +/** An I/O bundle for dequeuing data with valid/ready handshaking. + * Initialization must be handled, if necessary, by the parent circuit + */ +class DeqIO[T <: Data](gen: T) extends DecoupledIO(gen) with Flipped +{ + /** Assert ready on this port and return the associated data bits. + * This is typically used when valid has been asserted by the producer side. + * @param b ignored + * @return the data for this device, + */ + def deq(b: Boolean = false): T = { ready := Bool(true); bits } + + /** Initialize this Bundle. + * NOTE: This method of initialization is still being discussed and could change in the + * future. + */ + def init(): Unit = { + ready := Bool(false) + } + override def cloneType: this.type = { new DeqIO(gen).asInstanceOf[this.type]; } +} + +/** An I/O bundle for dequeuing data with valid/ready handshaking */ +class DecoupledIOC[+T <: Data](gen: T) extends Bundle +{ + val ready = Bool(INPUT) + val valid = Bool(OUTPUT) + val bits = gen.cloneType.asOutput +} + +/** 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 +{ + /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ + val enq = Decoupled(gen.cloneType).flip() + /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ + val deq = Decoupled(gen.cloneType) + /** The current amount of data in the queue */ + val count = UInt(OUTPUT, log2Up(entries + 1)) +} + +/** A hardware module implementing a Queue + * @param gen The type of data to queue + * @param entries The max number of entries in the queue + * @param pipe True if a single entry queue can run at full throughput (like a pipeline). The ''ready'' signals are + * 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. + * + * Example usage: + * {{{ val q = new Queue(UInt(), 16) + * q.io.enq <> producer.io.out + * consumer.io.in <> q.io.deq }}} + */ +class Queue[T <: Data](gen: T, val entries: Int, + pipe: Boolean = false, + flow: Boolean = false, + override_reset: Option[Bool] = None) +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)) + + val io = new QueueIO(gen, entries) + + val ram = Mem(entries, gen) + val enq_ptr = Counter(entries) + val deq_ptr = Counter(entries) + val maybe_full = Reg(init=Bool(false)) + + val ptr_match = enq_ptr.value === deq_ptr.value + val empty = ptr_match && !maybe_full + val full = ptr_match && maybe_full + val do_enq = Wire(init=io.enq.fire()) + val do_deq = Wire(init=io.deq.fire()) + + when (do_enq) { + ram(enq_ptr.value) := io.enq.bits + enq_ptr.inc() + } + when (do_deq) { + deq_ptr.inc() + } + when (do_enq != do_deq) { + maybe_full := do_enq + } + + io.deq.valid := !empty + io.enq.ready := !full + io.deq.bits := ram(deq_ptr.value) + + if (flow) { + when (io.enq.valid) { io.deq.valid := Bool(true) } + when (empty) { + io.deq.bits := io.enq.bits + do_deq := Bool(false) + when (io.deq.ready) { do_enq := Bool(false) } + } + } + + if (pipe) { + when (io.deq.ready) { io.enq.ready := Bool(true) } + } + + val ptr_diff = enq_ptr.value - deq_ptr.value + if (isPow2(entries)) { + io.count := Cat(maybe_full && ptr_match, ptr_diff) + } else { + io.count := Mux(ptr_match, + Mux(maybe_full, + UInt(entries), UInt(0)), + Mux(deq_ptr.value > enq_ptr.value, + UInt(entries) + ptr_diff, ptr_diff)) + } +} + +/** Generic hardware queue. Required parameter entries controls + the depth of the queues. The width of the queue is determined + from the inputs. + + Example usage: + {{{ val q = Queue(Decoupled(UInt()), 16) + q.io.enq <> producer.io.out + consumer.io.in <> q.io.deq }}} + */ +object Queue +{ + def apply[T <: Data](enq: DecoupledIO[T], entries: Int = 2, pipe: Boolean = false): DecoupledIO[T] = { + val q = Module(new Queue(enq.bits.cloneType, entries, pipe)) + 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 + TransitName(q.io.deq, q) + } +} diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala new file mode 100644 index 00000000..20057197 --- /dev/null +++ b/src/main/scala/chisel3/util/Enum.scala @@ -0,0 +1,21 @@ +// See LICENSE for license details. + +/** Enum generators, allowing circuit constants to have more meaningful names. + */ + +package Chisel + +object Enum { + /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ + private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] = + (0 until n).map(x => nodeType.fromInt(x, log2Up(n))) + + /** create n enum values of given type */ + def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList + + /** create enum values of given type and names */ + def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap + + /** create enum values of given type and names */ + def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap +} diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala new file mode 100644 index 00000000..6a230022 --- /dev/null +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -0,0 +1,8 @@ +// See LICENSE for license details. + +package Chisel + +object ImplicitConversions { + implicit def intToUInt(x: Int): UInt = UInt(x) + implicit def booleanToBool(x: Boolean): Bool = Bool(x) +} diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala new file mode 100644 index 00000000..839b1d1f --- /dev/null +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -0,0 +1,22 @@ +// See LICENSE for license details. + +/** LFSRs in all shapes and sizes. + */ + +package Chisel + +// scalastyle:off magic.number +/** linear feedback shift register + */ +object LFSR16 +{ + def apply(increment: Bool = Bool(true)): UInt = + { + val width = 16 + val lfsr = Reg(init=UInt(1, width)) + when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } + lfsr + } +} +// scalastyle:on magic.number + diff --git a/src/main/scala/chisel3/util/Lookup.scala b/src/main/scala/chisel3/util/Lookup.scala new file mode 100644 index 00000000..54922fc4 --- /dev/null +++ b/src/main/scala/chisel3/util/Lookup.scala @@ -0,0 +1,17 @@ +// See LICENSE for license details. + +package Chisel + +object ListLookup { + def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = { + val map = mapping.map(m => (m._1 === addr, m._2)) + default.zipWithIndex map { case (d, i) => + map.foldRight(d)((m, n) => Mux(m._1, m._2(i), n)) + } + } +} + +object Lookup { + def apply[T <: Bits](addr: UInt, default: T, mapping: Seq[(BitPat, T)]): T = + ListLookup(addr, List(default), mapping.map(m => (m._1, List(m._2))).toArray).head +} diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala new file mode 100644 index 00000000..5f8212d8 --- /dev/null +++ b/src/main/scala/chisel3/util/Math.scala @@ -0,0 +1,42 @@ +// See LICENSE for license details. + +/** Scala-land math helper functions, like logs. + */ + +package Chisel + +/** Compute the log2 rounded up with min value of 1 */ +object log2Up { + def apply(in: BigInt): Int = { + require(in >= 0) + 1 max (in-1).bitLength + } + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded up */ +object log2Ceil { + def apply(in: BigInt): Int = { + require(in > 0) + (in-1).bitLength + } + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded down with min value of 1 */ +object log2Down { + def apply(in: BigInt): Int = log2Up(in) - (if (isPow2(in)) 0 else 1) + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Compute the log2 rounded down */ +object log2Floor { + def apply(in: BigInt): Int = log2Ceil(in) - (if (isPow2(in)) 0 else 1) + def apply(in: Int): Int = apply(BigInt(in)) +} + +/** Check if an Integer is a power of 2 */ +object isPow2 { + def apply(in: BigInt): Boolean = in > 0 && ((in & (in-1)) == 0) + def apply(in: Int): Boolean = apply(BigInt(in)) +} diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala new file mode 100644 index 00000000..9d92321a --- /dev/null +++ b/src/main/scala/chisel3/util/Mux.scala @@ -0,0 +1,61 @@ +// See LICENSE for license details. + +/** Mux circuit generators. + */ + +package Chisel + +/** Builds a Mux tree out of the input signal vector using a one hot encoded + select signal. Returns the output of the Mux tree. + */ +object Mux1H +{ + def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = + apply(sel zip in) + def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in) + def apply[T <: Data](sel: UInt, in: Seq[T]): T = + apply((0 until in.size).map(sel(_)), in) + def apply(sel: UInt, in: UInt): Bool = (sel & in).orR +} + +/** Builds a Mux tree under the assumption that multiple select signals + can be enabled. Priority is given to the first select signal. + + Returns the output of the Mux tree. + */ +object PriorityMux +{ + def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in) + def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) + def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) +} + +/** MuxLookup creates a cascade of n Muxs to search for a key value */ +object MuxLookup { + /** @param key a key to search for + * @param default a default value if nothing is found + * @param mapping a sequence to search of keys and values + * @return the value found or the default if not + */ + def apply[S <: UInt, T <: Bits] (key: S, default: T, mapping: Seq[(S, T)]): T = { + var res = default + for ((k, v) <- mapping.reverse) + res = Mux(k === key, v, res) + res + } + +} + +/** MuxCase returns the first value that is enabled in a map of values */ +object MuxCase { + /** @param default the default value if none are enabled + * @param mapping a set of data values with associated enables + * @return the first value in mapping that is enabled */ + def apply[T <: Bits] (default: T, mapping: Seq[(Bool, T)]): T = { + var res = default + for ((t, v) <- mapping.reverse){ + res = Mux(t, v, res) + } + res + } +} diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala new file mode 100644 index 00000000..73f27403 --- /dev/null +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -0,0 +1,62 @@ +// See LICENSE for license details. + +/** Circuit generators for working with one-hot representations. + */ + +package Chisel + +/** Converts from One Hot Encoding to a UInt indicating which bit is active + * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ +object OHToUInt { + def apply(in: Seq[Bool]): UInt = apply(Vec(in)) + def apply(in: Vec[Bool]): UInt = apply(in.toBits, in.size) + def apply(in: Bits): UInt = apply(in, in.getWidth) + + def apply(in: Bits, width: Int): UInt = { + if (width <= 2) { + Log2(in, width) + } else { + val mid = 1 << (log2Up(width)-1) + val hi = in(width-1, mid) + val lo = in(mid-1, 0) + Cat(hi.orR, apply(hi | lo, mid)) + } + } +} + +/** @return the bit position of the trailing 1 in the input vector + * with the assumption that multiple bits of the input bit vector can be set + * @example {{{ data_out := PriorityEncoder(data_in) }}} + */ +object PriorityEncoder { + def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) + def apply(in: Bits): UInt = apply(in.toBools) +} + +/** Returns the one hot encoding of the input UInt. + */ +object UIntToOH +{ + def apply(in: UInt, width: Int = -1): UInt = + if (width == -1) { + UInt(1) << in + } else { + (UInt(1) << in(log2Up(width)-1,0))(width-1,0) + } +} + +/** Returns a bit vector in which only the least-significant 1 bit in + the input vector, if any, is set. + */ +object PriorityEncoderOH +{ + private def encode(in: Seq[Bool]): UInt = { + val outs = Seq.tabulate(in.size)(i => UInt(BigInt(1) << i, in.size)) + PriorityMux(in :+ Bool(true), outs :+ UInt(0, in.size)) + } + def apply(in: Seq[Bool]): Seq[Bool] = { + val enc = encode(in) + Seq.tabulate(in.size)(enc(_)) + } + def apply(in: Bits): UInt = encode((0 until in.getWidth).map(i => in(i))) +} diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala new file mode 100644 index 00000000..6584a4bf --- /dev/null +++ b/src/main/scala/chisel3/util/Reg.scala @@ -0,0 +1,55 @@ +// See LICENSE for license details. + +/** Variations and helpers for registers. + */ + +package Chisel + +object RegNext { + + def apply[T <: Data](next: T): T = Reg[T](null.asInstanceOf[T], next, null.asInstanceOf[T]) + + def apply[T <: Data](next: T, init: T): T = Reg[T](null.asInstanceOf[T], next, init) + +} + +object RegInit { + + def apply[T <: Data](init: T): T = Reg[T](null.asInstanceOf[T], null.asInstanceOf[T], init) + +} + +/** A register with an Enable signal */ +object RegEnable +{ + def apply[T <: Data](updateData: T, enable: Bool): T = { + val r = Reg(updateData) + when (enable) { r := updateData } + r + } + def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = { + val r = RegInit(resetData) + when (enable) { r := updateData } + r + } +} + +/** Returns the n-cycle delayed version of the input signal. + */ +object ShiftRegister +{ + /** @param in input to delay + * @param n number of cycles to delay + * @param en enable the shift */ + def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = + { + // The order of tests reflects the expected use cases. + if (n == 1) { + RegEnable(in, en) + } else if (n != 0) { + RegNext(apply(in, n-1, en)) + } else { + in + } + } +} diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala new file mode 100644 index 00000000..ec5a11cc --- /dev/null +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -0,0 +1,21 @@ +package Chisel + +import internal.HasId + +object TransitName { + // The purpose of this is to allow a library to 'move' a name call to a more + // appropriate place. + // For example, a library factory function may create a module and return + // the io. The only user-exposed field is that given IO, which can't use + // any name supplied by the user. This can add a hook so that the supplied + // name then names the Module. + // See Queue companion object for working example + def apply[T<:HasId](from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name)}) + from + } + def withSuffix[T<:HasId](suffix: String)(from: T, to: HasId): T = { + from.addPostnameHook((given_name: String) => {to.suggestName(given_name+suffix)}) + from + } +} diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala new file mode 100644 index 00000000..9e2202bb --- /dev/null +++ b/src/main/scala/chisel3/util/Valid.scala @@ -0,0 +1,59 @@ +// See LICENSE for license details. + +/** Wrappers for valid interfaces and associated circuit generators using them. + */ + +package Chisel + +/** An I/O Bundle containing data and a signal determining if it is valid */ +class ValidIO[+T <: Data](gen2: T) extends Bundle +{ + val valid = Bool(OUTPUT) + val bits = gen2.cloneType.asOutput + def fire(dummy: Int = 0): Bool = valid + override def cloneType: this.type = new ValidIO(gen2).asInstanceOf[this.type] +} + +/** Adds a valid protocol to any interface. The standard used is + that the consumer uses the flipped interface. +*/ +object Valid { + def apply[T <: Data](gen: T): ValidIO[T] = new ValidIO(gen) +} + +/** 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. + + 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): ValidIO[T] = { + if (latency == 0) { + val out = Wire(Valid(enqBits)) + out.valid <> enqValid + out.bits <> enqBits + out + } else { + val v = Reg(Bool(), next=enqValid, init=Bool(false)) + val b = RegEnable(enqBits, enqValid) + apply(v, b, latency-1) + } + } + def apply[T <: Data](enqValid: Bool, enqBits: T): ValidIO[T] = apply(enqValid, enqBits, 1) + def apply[T <: Data](enq: ValidIO[T], latency: Int = 1): ValidIO[T] = apply(enq.valid, enq.bits, latency) +} + +class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module +{ + val io = new Bundle { + val enq = Valid(gen).flip + val deq = Valid(gen) + } + + io.deq <> Pipe(io.enq, latency) +} -- cgit v1.2.3 From 12810b5efe6a8f872fbc1c63cdfb835ca354624f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 6 Jul 2016 09:31:47 -0700 Subject: Update Chisel -> chisel3 references. --- src/main/scala/chisel3/util/Arbiter.scala | 4 +++- src/main/scala/chisel3/util/BitPat.scala | 5 +++-- src/main/scala/chisel3/util/Bitwise.scala | 5 ++++- src/main/scala/chisel3/util/Cat.scala | 5 ++++- src/main/scala/chisel3/util/CircuitMath.scala | 4 +++- src/main/scala/chisel3/util/Conditional.scala | 8 ++++++-- src/main/scala/chisel3/util/Counter.scala | 4 +++- src/main/scala/chisel3/util/Decoupled.scala | 4 +++- src/main/scala/chisel3/util/Enum.scala | 4 +++- src/main/scala/chisel3/util/ImplicitConversions.scala | 4 +++- src/main/scala/chisel3/util/LFSR.scala | 4 +++- src/main/scala/chisel3/util/Lookup.scala | 4 +++- src/main/scala/chisel3/util/Math.scala | 4 +++- src/main/scala/chisel3/util/Mux.scala | 9 ++++++--- src/main/scala/chisel3/util/OneHot.scala | 4 +++- src/main/scala/chisel3/util/Reg.scala | 4 +++- src/main/scala/chisel3/util/TransitName.scala | 3 ++- src/main/scala/chisel3/util/Valid.scala | 4 +++- 18 files changed, 61 insertions(+), 22 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 16ae9be5..eb541977 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -3,7 +3,9 @@ /** Arbiters in all shapes and sizes. */ -package Chisel +package chisel3.util + +import chisel3._ /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 96206f63..9eb5cf67 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -1,10 +1,11 @@ // See LICENSE for license details. -package Chisel +package chisel3.util import scala.language.experimental.macros -import Chisel.internal.sourceinfo.{SourceInfo, SourceInfoTransform} +import chisel3._ +import chisel3.internal.sourceinfo.{SourceInfo, SourceInfoTransform} object BitPat { /** Parses a bit pattern string into (bits, mask, width). diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index 239a295e..ab1ff550 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -3,7 +3,10 @@ /** Miscellaneous circuit generators operating on bits. */ -package Chisel +package chisel3.util + +import chisel3._ +import chisel3.core.SeqUtils object FillInterleaved { diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala index dd706e62..469bf9ab 100644 --- a/src/main/scala/chisel3/util/Cat.scala +++ b/src/main/scala/chisel3/util/Cat.scala @@ -1,6 +1,9 @@ // See LICENSE for license details. -package Chisel +package chisel3.util + +import chisel3._ +import chisel3.core.SeqUtils object Cat { /** Combine data elements together diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 06cab903..1174c71c 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -3,7 +3,9 @@ /** Circuit-land math operations. */ -package Chisel +package chisel3.util + +import chisel3._ /** Compute Log2 with truncation of a UInt in hardware using a Mux Tree * An alternative interpretation is it computes the minimum number of bits needed to represent x diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 9cab25ef..6218feb0 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -3,13 +3,15 @@ /** Conditional blocks. */ -package Chisel +package chisel3.util import scala.language.reflectiveCalls import scala.language.experimental.macros import scala.reflect.runtime.universe._ import scala.reflect.macros.blackbox._ +import chisel3._ + /** This is identical to [[Chisel.when when]] with the condition inverted */ object unless { // scalastyle:ignore object.name def apply(c: Bool)(block: => Unit) { @@ -59,7 +61,9 @@ object switch { // scalastyle:ignore object.name def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._ val sc = c.universe.internal.reificationSupport.freshTermName("sc") def extractIsStatement(tree: Tree): List[c.universe.Tree] = tree match { - case q"Chisel.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + // TODO: remove when Chisel compatibility package is removed + case q"Chisel.`package`.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") + case q"chisel3.util.is.apply( ..$params )( ..$body )" => List(q"$sc.is( ..$params )( ..$body )") case b => throw new Exception(s"Cannot include blocks that do not begin with is() in switch.") } val q"..$body" = x diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 872e830a..40615769 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -1,6 +1,8 @@ // See LICENSE for license details. -package Chisel +package chisel3.util + +import chisel3._ /** A counter module * @param n number of counts before the counter resets (or one more than the diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 8e045855..339fde7c 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -3,7 +3,9 @@ /** Wrappers for ready-valid (Decoupled) interfaces and associated circuit generators using them. */ -package Chisel +package chisel3.util + +import chisel3._ /** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ class DecoupledIO[+T <: Data](gen: T) extends Bundle diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 20057197..4ecc243b 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -3,7 +3,9 @@ /** Enum generators, allowing circuit constants to have more meaningful names. */ -package Chisel +package chisel3.util + +import chisel3._ object Enum { /** Returns a sequence of Bits subtypes with values from 0 until n. Helper method. */ diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 6a230022..4d816a19 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -1,6 +1,8 @@ // See LICENSE for license details. -package Chisel +package chisel3.util + +import chisel3._ object ImplicitConversions { implicit def intToUInt(x: Int): UInt = UInt(x) diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index 839b1d1f..a30c276f 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -3,7 +3,9 @@ /** LFSRs in all shapes and sizes. */ -package Chisel +package chisel3.util + +import chisel3._ // scalastyle:off magic.number /** linear feedback shift register diff --git a/src/main/scala/chisel3/util/Lookup.scala b/src/main/scala/chisel3/util/Lookup.scala index 54922fc4..9e909c0c 100644 --- a/src/main/scala/chisel3/util/Lookup.scala +++ b/src/main/scala/chisel3/util/Lookup.scala @@ -1,6 +1,8 @@ // See LICENSE for license details. -package Chisel +package chisel3.util + +import chisel3._ object ListLookup { def apply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] = { diff --git a/src/main/scala/chisel3/util/Math.scala b/src/main/scala/chisel3/util/Math.scala index 5f8212d8..73665f0f 100644 --- a/src/main/scala/chisel3/util/Math.scala +++ b/src/main/scala/chisel3/util/Math.scala @@ -3,7 +3,9 @@ /** Scala-land math helper functions, like logs. */ -package Chisel +package chisel3.util + +import chisel3._ /** Compute the log2 rounded up with min value of 1 */ object log2Up { diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala index 9d92321a..9956a7e3 100644 --- a/src/main/scala/chisel3/util/Mux.scala +++ b/src/main/scala/chisel3/util/Mux.scala @@ -3,7 +3,10 @@ /** Mux circuit generators. */ -package Chisel +package chisel3.util + +import chisel3._ +import chisel3.core.SeqUtils /** Builds a Mux tree out of the input signal vector using a one hot encoded select signal. Returns the output of the Mux tree. @@ -37,7 +40,7 @@ object MuxLookup { * @param mapping a sequence to search of keys and values * @return the value found or the default if not */ - def apply[S <: UInt, T <: Bits] (key: S, default: T, mapping: Seq[(S, T)]): T = { + def apply[S <: UInt, T <: Data] (key: S, default: T, mapping: Seq[(S, T)]): T = { var res = default for ((k, v) <- mapping.reverse) res = Mux(k === key, v, res) @@ -51,7 +54,7 @@ object MuxCase { /** @param default the default value if none are enabled * @param mapping a set of data values with associated enables * @return the first value in mapping that is enabled */ - def apply[T <: Bits] (default: T, mapping: Seq[(Bool, T)]): T = { + def apply[T <: Data] (default: T, mapping: Seq[(Bool, T)]): T = { var res = default for ((t, v) <- mapping.reverse){ res = Mux(t, v, res) diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 73f27403..820c72d6 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -3,7 +3,9 @@ /** Circuit generators for working with one-hot representations. */ -package Chisel +package chisel3.util + +import chisel3._ /** Converts from One Hot Encoding to a UInt indicating which bit is active * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 6584a4bf..81de4754 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -3,7 +3,9 @@ /** Variations and helpers for registers. */ -package Chisel +package chisel3.util + +import chisel3._ object RegNext { diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala index ec5a11cc..f36f926f 100644 --- a/src/main/scala/chisel3/util/TransitName.scala +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -1,5 +1,6 @@ -package Chisel +package chisel3.util +import chisel3._ import internal.HasId object TransitName { diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 9e2202bb..78187ff6 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -3,7 +3,9 @@ /** Wrappers for valid interfaces and associated circuit generators using them. */ -package Chisel +package chisel3.util + +import chisel3._ /** An I/O Bundle containing data and a signal determining if it is valid */ class ValidIO[+T <: Data](gen2: T) extends Bundle -- cgit v1.2.3 From 3120eefc8a73b5ab3d8f909445a3e004b5e60cc6 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 19 Jul 2016 15:08:22 -0700 Subject: Incorporate connection logic. Compiles but fails tests. --- src/main/scala/chisel3/util/Decoupled.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 73f58ed4..4a6b72e9 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -12,8 +12,8 @@ class DecoupledIO[+T <: Data](gen: T) extends Bundle { val ready = Input(Bool()) val valid = Output(Bool()) - val bits = Output(gen.newType) - override protected def cloneType: this.type = DecoupledIO(gen).asInstanceOf[this.type] + val bits = Output(gen.cloneType) + override def cloneType: this.type = DecoupledIO(gen).asInstanceOf[this.type] } object DecoupledIO { @@ -30,7 +30,7 @@ object DecoupledIO { * @return dat. */ def enq(dat: T): T = { - target.valid := true.asBool + target.valid := Bool(true) target.bits := dat dat } @@ -38,7 +38,7 @@ object DecoupledIO { /** Indicate no enqueue occurs. Valid is set to false, and all bits are set to zero. */ def noenq(): Unit = { - target.valid := false.asBool + target.valid := Bool(false) target.bits := target.bits.fromBits(0.asUInt) } @@ -48,17 +48,17 @@ object DecoupledIO { * @return the data for this device, */ def deq(): T = { - target.ready := true.asBool + target.ready := Bool(true) target.bits } /** Indicate no dequeue occurs. Ready is set to false */ def nodeq(): Unit = { - target.ready := false.asBool + target.ready := Bool(false) } } - override def cloneType: this.type = { new DeqIO(gen).asInstanceOf[this.type]; } +// override def cloneType: this.type = { DeqIO(gen).asInstanceOf[this.type]; } } object EnqIO { -- cgit v1.2.3 From 28e80311f172ae4d1d477e8bb47ca3719c9a8fc5 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 20 Jul 2016 13:28:15 -0700 Subject: Compile ok. Need to convert UInt(x) into UInt.Lit(x) or UInt.width(x) --- src/main/scala/chisel3/util/BitPat.scala | 4 ++-- src/main/scala/chisel3/util/Decoupled.scala | 6 +++++- src/main/scala/chisel3/util/Valid.scala | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 9eb5cf67..3ae192a2 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -75,7 +75,7 @@ object BitPat { // TODO: Break out of Core? (this doesn't involve FIRRTL generation) /** Bit patterns are literals with masks, used to represent values with don't * cares. Equality comparisons will ignore don't care bits (for example, - * BitPat(0b10?1) === UInt(0b1001) and UInt(0b1011)). + * BitPat(0b10?1) === 0b1001.asUInt and 0b1011.asUInt. */ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def getWidth: Int = width @@ -83,7 +83,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg def != (that: UInt): Bool = macro SourceInfoTransform.thatArg - def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = UInt(value) === (that & UInt(mask)) + def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = value.asUInt === (that & mask.asUInt) def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 4a6b72e9..fb1ee6b9 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -58,7 +58,11 @@ object DecoupledIO { target.ready := Bool(false) } } -// override def cloneType: this.type = { DeqIO(gen).asInstanceOf[this.type]; } +// override def cloneType: this.type = { +// val clone = DeqIO(gen).asInstanceOf[this.type] +// clone.unBind() +// clone +// } } object EnqIO { diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 4078a76a..5641f0f2 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -13,7 +13,11 @@ class Valid[+T <: Data](gen: T) extends Bundle val valid = Output(Bool()) val bits = Output(gen.cloneType) def fire(dummy: Int = 0): Bool = valid - override def cloneType: this.type = Valid(gen).asInstanceOf[this.type] + override def cloneType: this.type = { + val clone = Valid(gen).asInstanceOf[this.type] + clone.unBind() + clone + } } /** Adds a valid protocol to any interface */ -- cgit v1.2.3 From 2dce378deda1cc33833eb378c89a1c5415817bae Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 20 Jul 2016 14:49:35 -0700 Subject: Distinguish between ?Int.Lit and ?Int.width --- src/main/scala/chisel3/util/Arbiter.scala | 12 ++++++------ src/main/scala/chisel3/util/CircuitMath.scala | 4 ++-- src/main/scala/chisel3/util/Counter.scala | 10 +++++----- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- src/main/scala/chisel3/util/ImplicitConversions.scala | 2 +- src/main/scala/chisel3/util/OneHot.scala | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index a5397682..44cc88b6 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -36,7 +36,7 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo if (count > 1) { val lockCount = Counter(count) val lockIdx = Reg(UInt()) - val locked = lockCount.value =/= UInt(0) + val locked = lockCount.value =/= UInt.Lit(0) val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(Bool(true)) when (io.out.firing && wantsLock) { @@ -46,7 +46,7 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo when (locked) { io.chosen := lockIdx } for ((in, (g, i)) <- io.in zip grant.zipWithIndex) - in.ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready + in.ready := Mux(locked, lockIdx === UInt.Lit(i), g) && io.out.ready } else { for ((in, g) <- io.in zip grant) in.ready := g && io.out.ready @@ -66,9 +66,9 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ override lazy val choice = Wire(init=UInt(n-1)) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt(i) } + when (io.in(i).valid) { choice := UInt.Lit(i) } for (i <- n-1 to 1 by -1) - when (validMask(i)) { choice := UInt(i) } + when (validMask(i)) { choice := UInt.Lit(i) } } class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) @@ -77,7 +77,7 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T override lazy val choice = Wire(init=UInt(n-1)) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt(i) } + when (io.in(i).valid) { choice := UInt.Lit(i) } } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -107,7 +107,7 @@ class Arbiter[T <: Data](gen: T, n: Int) extends Module { io.out.bits := io.in(n-1).bits for (i <- n-2 to 0 by -1) { when (io.in(i).valid) { - io.chosen := UInt(i) + io.chosen := UInt.Lit(i) io.out.bits := io.in(i).bits } } diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 1174c71c..5e93b009 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -11,12 +11,12 @@ import chisel3._ * An alternative interpretation is it computes the minimum number of bits needed to represent x * @example * {{{ data_out := Log2(data_in) }}} - * @note Truncation is used so Log2(UInt(12412)) = 13*/ + * @note Truncation is used so Log2(UInt.Lit(12412)) = 13*/ object Log2 { /** Compute the Log2 on the least significant n bits of x */ def apply(x: Bits, width: Int): UInt = { if (width < 2) { - UInt(0) + UInt.Lit(0) } else if (width == 2) { x(1) } else { diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 40615769..05d8fba8 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -10,17 +10,17 @@ import chisel3._ */ class Counter(val n: Int) { require(n >= 0) - val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) + val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt.Lit(0) /** Increment the counter, returning whether the counter currently is at the * maximum and will wrap. The incremented value is registered and will be * visible on the next cycle. */ def inc(): Bool = { if (n > 1) { - val wrap = value === UInt(n-1) - value := value + UInt(1) + val wrap = value === UInt.Lit(n-1) + value := value + UInt.Lit(1) if (!isPow2(n)) { - when (wrap) { value := UInt(0) } + when (wrap) { value := UInt.Lit(0) } } wrap } else { @@ -33,7 +33,7 @@ class Counter(val n: Int) { * Example Usage: * {{{ val countOn = Bool(true) // increment counter every clock cycle * val myCounter = Counter(countOn, n) - * when ( myCounter.value === UInt(3) ) { ... } }}}*/ + * when ( myCounter.value === UInt.Lit(3) ) { ... } }}}*/ object Counter { def apply(n: Int): Counter = new Counter(n) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index fb1ee6b9..5958c744 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -153,9 +153,9 @@ extends Module(override_reset=override_reset) { } else { io.count := Mux(ptr_match, Mux(maybe_full, - UInt(entries), UInt(0)), + UInt.Lit(entries), UInt.Lit(0)), Mux(deq_ptr.value > enq_ptr.value, - UInt(entries) + ptr_diff, ptr_diff)) + UInt.Lit(entries) + ptr_diff, ptr_diff)) } } diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 4d816a19..3a9089c5 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -5,6 +5,6 @@ package chisel3.util import chisel3._ object ImplicitConversions { - implicit def intToUInt(x: Int): UInt = UInt(x) + implicit def intToUInt(x: Int): UInt = UInt.Lit(x) implicit def booleanToBool(x: Boolean): Bool = Bool(x) } diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 820c72d6..8a5caf44 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -41,9 +41,9 @@ object UIntToOH { def apply(in: UInt, width: Int = -1): UInt = if (width == -1) { - UInt(1) << in + UInt.Lit(1) << in } else { - (UInt(1) << in(log2Up(width)-1,0))(width-1,0) + (UInt.Lit(1) << in(log2Up(width)-1,0))(width-1,0) } } -- cgit v1.2.3 From 1fa57cc3f76bc3e5de7e6b943abe70becdcb2295 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 20 Jul 2016 17:08:55 -0700 Subject: More literal/width rangling. --- src/main/scala/chisel3/util/Arbiter.scala | 10 +++++----- src/main/scala/chisel3/util/Bitwise.scala | 2 +- src/main/scala/chisel3/util/CircuitMath.scala | 2 +- src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/main/scala/chisel3/util/OneHot.scala | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 44cc88b6..0ece3a0a 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -11,7 +11,7 @@ import chisel3._ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { val in = Flipped(Vec(n, DecoupledIO(gen))) val out = DecoupledIO(gen) - val chosen = Output(UInt(log2Up(n))) + val chosen = Output(UInt.width(log2Up(n))) } /** Arbiter Control determining which producer has access */ @@ -56,7 +56,7 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { lazy val lastGrant = RegEnable(io.chosen, io.out.firing) - lazy val grantMask = (0 until n).map(UInt(_) > lastGrant) + lazy val grantMask = (0 until n).map(UInt.Lit(_) > lastGrant) lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } override def grant: Seq[Bool] = { @@ -64,7 +64,7 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) } - override lazy val choice = Wire(init=UInt(n-1)) + override lazy val choice = Wire(init=UInt.Lit(n-1)) for (i <- n-2 to 0 by -1) when (io.in(i).valid) { choice := UInt.Lit(i) } for (i <- n-1 to 1 by -1) @@ -75,7 +75,7 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T extends LockingArbiterLike[T](gen, n, count, needsLock) { def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) - override lazy val choice = Wire(init=UInt(n-1)) + override lazy val choice = Wire(init=UInt.Lit(n-1)) for (i <- n-2 to 0 by -1) when (io.in(i).valid) { choice := UInt.Lit(i) } } @@ -103,7 +103,7 @@ class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) class Arbiter[T <: Data](gen: T, n: Int) extends Module { val io = IO(new ArbiterIO(gen, n)) - io.chosen := UInt(n-1) + io.chosen := UInt.Lit(n-1) io.out.bits := io.in(n-1).bits for (i <- n-2 to 0 by -1) { when (io.in(i).valid) { diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index ab1ff550..b2a9a28c 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -27,7 +27,7 @@ object Fill { /** Fan out x n times */ def apply(n: Int, x: UInt): UInt = { n match { - case 0 => UInt(width=0) + case 0 => UInt.width(0) case 1 => x case y if n > 1 => val p2 = Array.ofDim[UInt](log2Up(n + 1)) diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 5e93b009..8f8bde4a 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -20,7 +20,7 @@ object Log2 { } else if (width == 2) { x(1) } else { - Mux(x(width-1), UInt(width-1), apply(x, width-1)) + Mux(x(width-1), UInt.width(width-1), apply(x, width-1)) } } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 5958c744..037f9a22 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -82,7 +82,7 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ val deq = DeqIO(gen) /** The current amount of data in the queue */ - val count = Output(UInt(log2Up(entries + 1))) + val count = Output(UInt.width(log2Up(entries + 1))) } /** A hardware module implementing a Queue diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 8a5caf44..c1f94ba6 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -31,7 +31,7 @@ object OHToUInt { * @example {{{ data_out := PriorityEncoder(data_in) }}} */ object PriorityEncoder { - def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) + def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt.Lit(_))) def apply(in: Bits): UInt = apply(in.toBools) } -- cgit v1.2.3 From 7c9043859994b32bb07d2fce4ae61a7a3362a1b3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 21 Jul 2016 17:12:06 -0700 Subject: Introduce chiselCloneType to distinguish from cloneType. Still fails one test - DirectionSpec in Direction.scala --- src/main/scala/chisel3/util/Decoupled.scala | 8 +++----- src/main/scala/chisel3/util/Reg.scala | 4 ++-- src/main/scala/chisel3/util/Valid.scala | 8 ++------ 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 037f9a22..76bf4842 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -12,7 +12,7 @@ class DecoupledIO[+T <: Data](gen: T) extends Bundle { val ready = Input(Bool()) val valid = Output(Bool()) - val bits = Output(gen.cloneType) + val bits = Output(gen.chiselCloneType) override def cloneType: this.type = DecoupledIO(gen).asInstanceOf[this.type] } @@ -59,9 +59,7 @@ object DecoupledIO { } } // override def cloneType: this.type = { -// val clone = DeqIO(gen).asInstanceOf[this.type] -// clone.unBind() -// clone +// DeqIO(gen).asInstanceOf[this.type] // } } @@ -171,7 +169,7 @@ extends Module(override_reset=override_reset) { object Queue { def apply[T <: Data](enq: DecoupledIO[T], entries: Int = 2, pipe: Boolean = false): DecoupledIO[T] = { - val q = Module(new Queue(enq.bits.cloneType, entries, pipe)) + val q = Module(new Queue(enq.bits.chiselCloneType, entries, pipe)) 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 diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 81de4754..f77a9667 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -26,12 +26,12 @@ object RegEnable { def apply[T <: Data](updateData: T, enable: Bool): T = { val r = Reg(updateData) - when (enable) { r := updateData } + when (enable) { r := updateData.chiselCloneType } r } def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = { val r = RegInit(resetData) - when (enable) { r := updateData } + when (enable) { r := updateData.chiselCloneType } r } } diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 5641f0f2..743038f3 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -11,13 +11,9 @@ import chisel3._ class Valid[+T <: Data](gen: T) extends Bundle { val valid = Output(Bool()) - val bits = Output(gen.cloneType) + val bits = Output(gen.chiselCloneType) def fire(dummy: Int = 0): Bool = valid - override def cloneType: this.type = { - val clone = Valid(gen).asInstanceOf[this.type] - clone.unBind() - clone - } + override def cloneType: this.type = Valid(gen).asInstanceOf[this.type] } /** Adds a valid protocol to any interface */ -- cgit v1.2.3 From 7aa05590382b0528799ad5e9f1318ce42e409793 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 25 Jul 2016 14:06:51 -0700 Subject: Minimize differences with master. Remove .Lit(x) usage. Undo "private" scope change. Change "firing" back to "fire". Add package level NODIR definition. --- src/main/scala/chisel3/util/Arbiter.scala | 24 +++++++++++----------- src/main/scala/chisel3/util/CircuitMath.scala | 4 ++-- src/main/scala/chisel3/util/Counter.scala | 10 ++++----- src/main/scala/chisel3/util/Decoupled.scala | 10 ++++----- .../scala/chisel3/util/ImplicitConversions.scala | 2 +- src/main/scala/chisel3/util/OneHot.scala | 6 +++--- 6 files changed, 28 insertions(+), 28 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 0ece3a0a..5875b3f2 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -36,17 +36,17 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo if (count > 1) { val lockCount = Counter(count) val lockIdx = Reg(UInt()) - val locked = lockCount.value =/= UInt.Lit(0) + val locked = lockCount.value =/= UInt(0) val wantsLock = needsLock.map(_(io.out.bits)).getOrElse(Bool(true)) - when (io.out.firing && wantsLock) { + when (io.out.fire() && wantsLock) { lockIdx := io.chosen lockCount.inc() } when (locked) { io.chosen := lockIdx } for ((in, (g, i)) <- io.in zip grant.zipWithIndex) - in.ready := Mux(locked, lockIdx === UInt.Lit(i), g) && io.out.ready + in.ready := Mux(locked, lockIdx === UInt(i), g) && io.out.ready } else { for ((in, g) <- io.in zip grant) in.ready := g && io.out.ready @@ -55,8 +55,8 @@ abstract class LockingArbiterLike[T <: Data](gen: T, n: Int, count: Int, needsLo class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { - lazy val lastGrant = RegEnable(io.chosen, io.out.firing) - lazy val grantMask = (0 until n).map(UInt.Lit(_) > lastGrant) + lazy val lastGrant = RegEnable(io.chosen, io.out.fire()) + lazy val grantMask = (0 until n).map(UInt(_) > lastGrant) lazy val validMask = io.in zip grantMask map { case (in, g) => in.valid && g } override def grant: Seq[Bool] = { @@ -64,20 +64,20 @@ class LockingRRArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[ (0 until n).map(i => ctrl(i) && grantMask(i) || ctrl(i + n)) } - override lazy val choice = Wire(init=UInt.Lit(n-1)) + override lazy val choice = Wire(init=UInt(n-1)) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt.Lit(i) } + when (io.in(i).valid) { choice := UInt(i) } for (i <- n-1 to 1 by -1) - when (validMask(i)) { choice := UInt.Lit(i) } + when (validMask(i)) { choice := UInt(i) } } class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T => Bool] = None) extends LockingArbiterLike[T](gen, n, count, needsLock) { def grant: Seq[Bool] = ArbiterCtrl(io.in.map(_.valid)) - override lazy val choice = Wire(init=UInt.Lit(n-1)) + override lazy val choice = Wire(init=UInt(n-1)) for (i <- n-2 to 0 by -1) - when (io.in(i).valid) { choice := UInt.Lit(i) } + when (io.in(i).valid) { choice := UInt(i) } } /** Hardware module that is used to sequence n producers into 1 consumer. @@ -103,11 +103,11 @@ class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) class Arbiter[T <: Data](gen: T, n: Int) extends Module { val io = IO(new ArbiterIO(gen, n)) - io.chosen := UInt.Lit(n-1) + io.chosen := UInt(n-1) io.out.bits := io.in(n-1).bits for (i <- n-2 to 0 by -1) { when (io.in(i).valid) { - io.chosen := UInt.Lit(i) + io.chosen := UInt(i) io.out.bits := io.in(i).bits } } diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index 27bd7bfb..c809e14b 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -16,11 +16,11 @@ object Log2 { /** Compute the Log2 on the least significant n bits of x */ def apply(x: Bits, width: Int): UInt = { if (width < 2) { - UInt.Lit(0) + UInt(0) } else if (width == 2) { x(1) } else if (width <= divideAndConquerThreshold) { - Mux(x(width-1), UInt.Lit(width-1), apply(x, width-1)) + Mux(x(width-1), UInt(width-1), apply(x, width-1)) } else { val mid = 1 << (log2Ceil(width) - 1) val hi = x(width-1, mid) diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 05d8fba8..40615769 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -10,17 +10,17 @@ import chisel3._ */ class Counter(val n: Int) { require(n >= 0) - val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt.Lit(0) + val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) /** Increment the counter, returning whether the counter currently is at the * maximum and will wrap. The incremented value is registered and will be * visible on the next cycle. */ def inc(): Bool = { if (n > 1) { - val wrap = value === UInt.Lit(n-1) - value := value + UInt.Lit(1) + val wrap = value === UInt(n-1) + value := value + UInt(1) if (!isPow2(n)) { - when (wrap) { value := UInt.Lit(0) } + when (wrap) { value := UInt(0) } } wrap } else { @@ -33,7 +33,7 @@ class Counter(val n: Int) { * Example Usage: * {{{ val countOn = Bool(true) // increment counter every clock cycle * val myCounter = Counter(countOn, n) - * when ( myCounter.value === UInt.Lit(3) ) { ... } }}}*/ + * when ( myCounter.value === UInt(3) ) { ... } }}}*/ object Counter { def apply(n: Int): Counter = new Counter(n) diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 76bf4842..68c3ae88 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -23,7 +23,7 @@ object DecoupledIO { def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) implicit class AddMethodsToDecoupled[T<:Data](val target: DecoupledIO[T]) extends AnyVal { - def firing: Bool = target.ready && target.valid + def fire(): Bool = target.ready && target.valid /** push dat onto the output bits of this interface to let the consumer know it has happened. * @param dat the values to assign to bits. @@ -114,8 +114,8 @@ extends Module(override_reset=override_reset) { val ptr_match = enq_ptr.value === deq_ptr.value val empty = ptr_match && !maybe_full val full = ptr_match && maybe_full - val do_enq = Wire(init=io.enq.firing) - val do_deq = Wire(init=io.deq.firing) + val do_enq = Wire(init=io.enq.fire()) + val do_deq = Wire(init=io.deq.fire()) when (do_enq) { ram(enq_ptr.value) := io.enq.bits @@ -151,9 +151,9 @@ extends Module(override_reset=override_reset) { } else { io.count := Mux(ptr_match, Mux(maybe_full, - UInt.Lit(entries), UInt.Lit(0)), + UInt(entries), UInt(0)), Mux(deq_ptr.value > enq_ptr.value, - UInt.Lit(entries) + ptr_diff, ptr_diff)) + UInt(entries) + ptr_diff, ptr_diff)) } } diff --git a/src/main/scala/chisel3/util/ImplicitConversions.scala b/src/main/scala/chisel3/util/ImplicitConversions.scala index 3a9089c5..4d816a19 100644 --- a/src/main/scala/chisel3/util/ImplicitConversions.scala +++ b/src/main/scala/chisel3/util/ImplicitConversions.scala @@ -5,6 +5,6 @@ package chisel3.util import chisel3._ object ImplicitConversions { - implicit def intToUInt(x: Int): UInt = UInt.Lit(x) + implicit def intToUInt(x: Int): UInt = UInt(x) implicit def booleanToBool(x: Boolean): Bool = Bool(x) } diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 49661115..abede61e 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -31,7 +31,7 @@ object OHToUInt { * @example {{{ data_out := PriorityEncoder(data_in) }}} */ object PriorityEncoder { - def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt.Lit(_))) + def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) def apply(in: Bits): UInt = apply(in.toBools) } @@ -41,9 +41,9 @@ object UIntToOH { def apply(in: UInt, width: Int = -1): UInt = if (width == -1) { - UInt.Lit(1) << in + UInt(1) << in } else { - (UInt.Lit(1) << in(log2Up(width)-1,0))(width-1,0) + (UInt(1) << in(log2Up(width)-1,0))(width-1,0) } } -- cgit v1.2.3 From bdbc554c0ccf490dd75d57c57b171452ac3de14b Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 27 Jul 2016 08:59:11 -0700 Subject: Correct EnqIO/DeqIO Flipped-ness. --- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 68c3ae88..3ee363a2 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -64,10 +64,10 @@ object DecoupledIO { } object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) + def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) } object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) + def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) } /** An I/O Bundle for Queues -- cgit v1.2.3 From 87d69afd1c8f28d91c78e7a539f6bf7a908e2a1f Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 27 Jul 2016 09:35:02 -0700 Subject: Correct EnqIO/DeqIO Flipped-ness. --- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 3ee363a2..0d000f49 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -76,9 +76,9 @@ object DeqIO { class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle { /** I/O to enqueue data, is [[Chisel.DecoupledIO]] flipped */ - val enq = EnqIO(gen) + val enq = DeqIO(gen) /** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/ - val deq = DeqIO(gen) + val deq = EnqIO(gen) /** The current amount of data in the queue */ val count = Output(UInt.width(log2Up(entries + 1))) } -- cgit v1.2.3 From 8b66107bffac270be16196d5a852cf3e6808fb0a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sun, 31 Jul 2016 17:05:21 -0700 Subject: Fix two deprecation warnings --- src/main/scala/chisel3/util/OneHot.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index abede61e..7e04a8d7 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -11,7 +11,7 @@ import chisel3._ * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ object OHToUInt { def apply(in: Seq[Bool]): UInt = apply(Cat(in.reverse), in.size) - def apply(in: Vec[Bool]): UInt = apply(in.toBits, in.size) + def apply(in: Vec[Bool]): UInt = apply(in.asUInt, in.size) def apply(in: Bits): UInt = apply(in, in.getWidth) def apply(in: Bits, width: Int): UInt = { -- cgit v1.2.3 From ef74500b8ae2d3804a43aa5a1fecc59cfbea13f5 Mon Sep 17 00:00:00 2001 From: Colin Schmidt Date: Tue, 9 Aug 2016 10:51:04 -0700 Subject: counter(inc,n) example should reflect actual use (#252) --- src/main/scala/chisel3/util/Counter.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 40615769..1c95190b 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -32,8 +32,8 @@ class Counter(val n: Int) { /** Counter Object * Example Usage: * {{{ val countOn = Bool(true) // increment counter every clock cycle - * val myCounter = Counter(countOn, n) - * when ( myCounter.value === UInt(3) ) { ... } }}}*/ + * val (myCounterValue, myCounterWrap) = Counter(countOn, n) + * when ( myCounterValue === UInt(3) ) { ... } }}}*/ object Counter { def apply(n: Int): Counter = new Counter(n) -- cgit v1.2.3 From ddb7278760029be9d960ba8bf2b06ac8a8aac767 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Mon, 15 Aug 2016 22:48:14 -0700 Subject: Make "def width" a private API; expose isWidthKnown instead (#257) * Make "def width" a private API; expose isWidthKnown instead Resolves #256. Since width was used to determine whether getWidth would succeed, I added def isWidthKnown: Boolean but another option would be to expose something like def widthOption: Option[Int] ...thoughts? * Document getWidth/isWidthKnown * Add widthOption for more idiomatic Scala manipulation of widths --- src/main/scala/chisel3/util/BitPat.scala | 2 +- src/main/scala/chisel3/util/Bitwise.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index d476f957..26106080 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -68,7 +68,7 @@ object BitPat { */ def apply(x: UInt): BitPat = { require(x.isLit) - val len = if (x.width.known) x.getWidth else 0 + val len = if (x.isWidthKnown) x.getWidth else 0 apply("b" + x.litValue.toString(2).reverse.padTo(len, "0").reverse.mkString) } } diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index 3134d043..6451ab14 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -29,7 +29,7 @@ object Fill { n match { case 0 => UInt(width=0) case 1 => x - case _ if x.width.known && x.getWidth == 1 => + case _ if x.isWidthKnown && x.getWidth == 1 => Mux(x.toBool, UInt((BigInt(1) << n) - 1, n), UInt(0, n)) case _ if n > 1 => val p2 = Array.ofDim[UInt](log2Up(n + 1)) -- cgit v1.2.3 From f41f2533c55e506f7d5bf2ee0198de4d9a3dbea3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 16 Aug 2016 11:59:20 -0700 Subject: Reduce rocket-chip elaboration errors. --- src/main/scala/chisel3/util/Reg.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index f77a9667..37c28b14 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -25,13 +25,14 @@ object RegInit { object RegEnable { def apply[T <: Data](updateData: T, enable: Bool): T = { - val r = Reg(updateData) - when (enable) { r := updateData.chiselCloneType } + val clonedUpdateData = updateData.chiselCloneType + val r = Reg(clonedUpdateData) + when (enable) { r := updateData } r } def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = { val r = RegInit(resetData) - when (enable) { r := updateData.chiselCloneType } + when (enable) { r := updateData } r } } -- cgit v1.2.3 From 35c8e40b25f529da883e8ae91644fcc496e087da Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 22 Aug 2016 16:57:43 -0700 Subject: Purely cosmetic changes to placate the scalastyle checker. --- src/main/scala/chisel3/util/BitPat.scala | 6 +++--- src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/main/scala/chisel3/util/TransitName.scala | 4 +++- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index e79b882b..5de7a508 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -84,7 +84,7 @@ sealed class BitPat(val value: BigInt, val mask: BigInt, width: Int) { def =/= (that: UInt): Bool = macro SourceInfoTransform.thatArg def != (that: UInt): Bool = macro SourceInfoTransform.thatArg - def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = value.asUInt === (that & mask.asUInt) - def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) - def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that + def do_=== (that: UInt)(implicit sourceInfo: SourceInfo): Bool = value.asUInt === (that & mask.asUInt) // scalastyle:ignore method.name + def do_=/= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = !(this === that) // scalastyle:ignore method.name + def do_!= (that: UInt)(implicit sourceInfo: SourceInfo): Bool = this =/= that // scalastyle:ignore method.name } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 0d000f49..42f58ea9 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -103,7 +103,7 @@ class Queue[T <: Data](gen: T, val entries: Int, 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)) - + val io = IO(new QueueIO(gen, entries)) val ram = Mem(entries, gen) diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala index f36f926f..ce6cb60f 100644 --- a/src/main/scala/chisel3/util/TransitName.scala +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -1,3 +1,5 @@ +// See LICENSE for license details. + package chisel3.util import chisel3._ @@ -16,7 +18,7 @@ object TransitName { from } def withSuffix[T<:HasId](suffix: String)(from: T, to: HasId): T = { - from.addPostnameHook((given_name: String) => {to.suggestName(given_name+suffix)}) + from.addPostnameHook((given_name: String) => {to.suggestName(given_name + suffix)}) from } } -- cgit v1.2.3 From 6df3a785f8abe706838bc5b4b35c3374b6512f96 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 29 Aug 2016 12:17:48 -0700 Subject: Pass compileOptions as an implicit Module parameter. --- src/main/scala/chisel3/util/Arbiter.scala | 1 + src/main/scala/chisel3/util/Decoupled.scala | 1 + src/main/scala/chisel3/util/Valid.scala | 1 + 3 files changed, 3 insertions(+) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 5875b3f2..57e81708 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.NotStrict.NotStrictCompileOptions /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 42f58ea9..8064d19b 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.NotStrict.NotStrictCompileOptions /** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ class DecoupledIO[+T <: Data](gen: T) extends Bundle diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 743038f3..d465d18d 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.NotStrict.NotStrictCompileOptions /** An Bundle containing data and a signal determining if it is valid */ class Valid[+T <: Data](gen: T) extends Bundle -- cgit v1.2.3 From 62817134d222747f1eab34626fe7b1bb13b9f6df Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Mon, 29 Aug 2016 13:45:05 -0700 Subject: Rename CompileOptions implicit objects. --- src/main/scala/chisel3/util/Arbiter.scala | 2 +- src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/main/scala/chisel3/util/Valid.scala | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 57e81708..5d46b7b9 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.NotStrictCompileOptions +import chisel3.NotStrict.CompileOptions /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 8064d19b..63831d2f 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.NotStrictCompileOptions +import chisel3.NotStrict.CompileOptions /** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ class DecoupledIO[+T <: Data](gen: T) extends Bundle diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index d465d18d..ed4c3721 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.NotStrictCompileOptions +import chisel3.NotStrict.CompileOptions /** An Bundle containing data and a signal determining if it is valid */ class Valid[+T <: Data](gen: T) extends Bundle -- cgit v1.2.3 From 000bba093609b74d0dbbc73490edac9ed756aa65 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Tue, 30 Aug 2016 13:28:42 -0700 Subject: Explicitly clone the target type in noenq() to avoid "already bound" errors for io ports. --- src/main/scala/chisel3/util/Decoupled.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 63831d2f..5ce2583c 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -40,7 +40,8 @@ object DecoupledIO { */ def noenq(): Unit = { target.valid := Bool(false) - target.bits := target.bits.fromBits(0.asUInt) + // We want the type from the following, not any existing binding. + target.bits := target.bits.cloneType.fromBits(0.asUInt) } /** Assert ready on this port and return the associated data bits. -- cgit v1.2.3 From 4b88a5dd45337fa88178fe17324eef3661daf1b3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 1 Sep 2016 10:21:57 -0700 Subject: Move connection implicits from Module constructor to connection methods. Eliminate builder compileOptions. --- src/main/scala/chisel3/util/Counter.scala | 1 + src/main/scala/chisel3/util/LFSR.scala | 1 + src/main/scala/chisel3/util/Reg.scala | 1 + 3 files changed, 3 insertions(+) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 1c95190b..441f5c5b 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,6 +3,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions /** A counter module * @param n number of counts before the counter resets (or one more than the diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index a30c276f..7146af7e 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions // scalastyle:off magic.number /** linear feedback shift register diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 37c28b14..8a9c54a2 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -6,6 +6,7 @@ package chisel3.util import chisel3._ +import chisel3.Strict.CompileOptions object RegNext { -- cgit v1.2.3 From bb240453abf96b4c2d75ebb2cdc7e3159068431d Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Thu, 8 Sep 2016 13:02:22 -0700 Subject: Add IrrevocableIO alternative to DecoupledIO (#274) Add IrrevocableIO subclass of DecoupledIO that promises not to change .bits on a cycle after .valid is high and .ready is low--- src/main/scala/chisel3/util/Decoupled.scala | 99 ++++++++++++++++++++++++----- 1 file changed, 83 insertions(+), 16 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index f37a5c31..51f5bd6a 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -7,23 +7,68 @@ package chisel3.util import chisel3._ -/** An I/O Bundle with simple handshaking using valid and ready signals for data 'bits'*/ -class DecoupledIO[+T <: Data](gen: T) extends Bundle +/** 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 + * 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 { val ready = Bool(INPUT) val valid = Bool(OUTPUT) val bits = gen.cloneType.asOutput def fire(dummy: Int = 0): Bool = ready && valid - override def cloneType: this.type = new DecoupledIO(gen).asInstanceOf[this.type] } -/** Adds a ready-valid handshaking protocol to any interface. - * The standard used is that the consumer uses the flipped interface. +/** A concrete subclass of ReadyValidIO signalling that the user expects a + * "decoupled" interface: 'valid' indicates that the producer has + * put valid data in 'bits', and 'ready' indicates that the consumer is ready + * to accept the data this cycle. No requirements are placed on the signalling + * of ready or valid. */ -object Decoupled { +class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) +{ + override def cloneType: this.type = new DecoupledIO(gen).asInstanceOf[this.type] +} + +/** This factory adds a decoupled handshaking protocol to a data bundle. */ +object Decoupled +{ + /** Take any Data and wrap it in a DecoupledIO interface */ def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) + + /** Take an IrrevocableIO and cast it to a DecoupledIO. + * This cast is only safe to do in cases where the IrrevocableIO + * is being produced as an output. + */ + def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { + require(irr.bits.dir == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.") + val d = Wire(new DecoupledIO(irr.bits)) + d.bits := irr.bits + d.valid := irr.valid + irr.ready := d.ready + d + } +} + +/** A concrete subclass of ReadyValidIO that promises to not change + * the value of 'bits' after a cycle where 'valid' is high and 'ready' is low. + * Additionally, once 'valid' is raised it will never be lowered until after + * 'ready' has also been raised. + */ +class IrrevocableIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) +{ + override def cloneType: this.type = new IrrevocableIO(gen).asInstanceOf[this.type] +} + +/** Factory adds an irrevocable handshaking protocol to a data bundle. */ +object Irrevocable +{ + def apply[T <: Data](gen: T): IrrevocableIO[T] = new IrrevocableIO(gen) } + /** An I/O bundle for enqueuing data with valid/ready handshaking * Initialization must be handled, if necessary, by the parent circuit */ @@ -103,7 +148,8 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle * q.io.enq <> producer.io.out * consumer.io.in <> q.io.deq }}} */ -class Queue[T <: Data](gen: T, val entries: Int, +class Queue[T <: Data](gen: T, + val entries: Int, pipe: Boolean = false, flow: Boolean = false, override_reset: Option[Bool] = None) @@ -164,22 +210,43 @@ extends Module(override_reset=override_reset) { } } -/** Generic hardware queue. Required parameter entries controls - the depth of the queues. The width of the queue is determined - from the inputs. - - Example usage: - {{{ val q = Queue(Decoupled(UInt()), 16) - q.io.enq <> producer.io.out - consumer.io.in <> q.io.deq }}} +/** Factory for a generic hardware queue. Required parameter 'entries' controls + * the depth of the queues. The width of the queue is determined + * from the input 'enq'. + * + * Example usage: + * {{{ consumer.io.in <> Queue(producer.io.out, 16) }}} */ object Queue { - def apply[T <: Data](enq: DecoupledIO[T], entries: Int = 2, pipe: Boolean = false): DecoupledIO[T] = { + /** Create a queue and supply a DecoupledIO containing the product. */ + def apply[T <: Data]( + enq: ReadyValidIO[T], + entries: Int = 2, + pipe: Boolean = false, + flow: Boolean = false): DecoupledIO[T] = { val q = Module(new Queue(enq.bits.cloneType, entries, pipe)) 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 TransitName(q.io.deq, q) } + + /** Create a queue and supply a IrrevocableIO containing the product. + * Casting from Decoupled is safe here because we know the Queue has + * Irrevocable semantics; we didn't want to change the return type of + * apply() for backwards compatibility reasons. + */ + def irrevocable[T <: Data]( + enq: ReadyValidIO[T], + entries: Int = 2, + pipe: Boolean = false, + flow: Boolean = false): IrrevocableIO[T] = { + val deq = apply(enq, entries, pipe) + val irr = Wire(new IrrevocableIO(deq.bits)) + irr.bits := deq.bits + irr.valid := deq.valid + deq.ready := irr.ready + irr + } } -- cgit v1.2.3 From 19f5b7c6841bda318288990e643eb02fa22a49e2 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 9 Sep 2016 17:23:14 -0700 Subject: Convert to NotStrict for internal connection checks. --- src/main/scala/chisel3/util/Reg.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 8a9c54a2..33508dcd 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.Strict.CompileOptions +import chisel3.NotStrict.CompileOptions object RegNext { -- cgit v1.2.3 From 2ff229dac5f915e7f583cbf9cc8118674a4e52a5 Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Tue, 13 Sep 2016 15:51:18 -0700 Subject: Bugfix: actually pass flow parameter from Queue factory to Queue module constructor --- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 51f5bd6a..b2634bec 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -225,7 +225,7 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): DecoupledIO[T] = { - val q = Module(new Queue(enq.bits.cloneType, entries, pipe)) + 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 @@ -242,7 +242,7 @@ object Queue entries: Int = 2, pipe: Boolean = false, flow: Boolean = false): IrrevocableIO[T] = { - val deq = apply(enq, entries, pipe) + val deq = apply(enq, entries, pipe, flow) val irr = Wire(new IrrevocableIO(deq.bits)) irr.bits := deq.bits irr.valid := deq.valid -- cgit v1.2.3 From dbf4278afbc5ce157ab1b946681a364f20778352 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 15 Sep 2016 15:42:21 -0700 Subject: move AddMethodsToDecoupled to ReadyValid --- src/main/scala/chisel3/util/Decoupled.scala | 41 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index d178cec5..14637c9b 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -21,26 +21,9 @@ abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle val bits = Output(gen.chiselCloneType) } -object DecoupledIO { - /** Adds a ready-valid handshaking protocol to any interface. - * The standard used is that the consumer uses the flipped interface. - */ - def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) +object ReadyValidIO { - /** Take an IrrevocableIO and cast it to a DecoupledIO. - * This cast is only safe to do in cases where the IrrevocableIO - * is being produced as an output. - */ - def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { - require(getFirrtlDirection(irr.bits) == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.") - val d = Wire(new DecoupledIO(irr.bits)) - d.bits := irr.bits - d.valid := irr.valid - irr.ready := d.ready - d - } - - implicit class AddMethodsToDecoupled[T<:Data](val target: DecoupledIO[T]) extends AnyVal { + implicit class AddMethodsToReadyValid[T<:Data](val target: ReadyValidIO[T]) extends AnyVal { def fire(): Bool = target.ready && target.valid /** push dat onto the output bits of this interface to let the consumer know it has happened. @@ -77,6 +60,26 @@ object DecoupledIO { target.ready := Bool(false) } } +} + +object DecoupledIO { + /** Adds a ready-valid handshaking protocol to any interface. + * The standard used is that the consumer uses the flipped interface. + */ + def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) + + /** Take an IrrevocableIO and cast it to a DecoupledIO. + * This cast is only safe to do in cases where the IrrevocableIO + * is being produced as an output. + */ + def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { + require(getFirrtlDirection(irr.bits) == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.") + val d = Wire(new DecoupledIO(irr.bits)) + d.bits := irr.bits + d.valid := irr.valid + irr.ready := d.ready + d + } // override def cloneType: this.type = { // DeqIO(gen).asInstanceOf[this.type] // } -- cgit v1.2.3 From dda64c1dee16b5da15ac690bd3cd6759c3d5c032 Mon Sep 17 00:00:00 2001 From: Wesley W. Terpstra Date: Thu, 15 Sep 2016 19:08:30 -0700 Subject: Decoupled: cast DecoupledIO to IrrevocableIO as an input (#280) --- src/main/scala/chisel3/util/Decoupled.scala | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index b2634bec..77990777 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -66,6 +66,19 @@ class IrrevocableIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) object Irrevocable { def apply[T <: Data](gen: T): IrrevocableIO[T] = new IrrevocableIO(gen) + + /** Take a DecoupledIO and cast it to an IrrevocableIO. + * This cast is only safe to do in cases where the IrrevocableIO + * is being consumed as an input. + */ + def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = { + require(dec.bits.dir == INPUT, "Only safe to cast consumed Decoupled bits to Irrevocable.") + val i = Wire(new IrrevocableIO(dec.bits)) + dec.bits := i.bits + dec.valid := i.valid + i.ready := dec.ready + i + } } -- cgit v1.2.3 From 6d8acee760c8c41fcae2ab252161bac96e6954dc Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Fri, 16 Sep 2016 09:07:15 -0700 Subject: Rename DecoupledIO object to Decoupled (compatibility). --- src/main/scala/chisel3/util/Arbiter.scala | 4 ++-- src/main/scala/chisel3/util/Decoupled.scala | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 5d46b7b9..c80f1908 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -10,8 +10,8 @@ import chisel3.NotStrict.CompileOptions /** An I/O bundle for the Arbiter */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { - val in = Flipped(Vec(n, DecoupledIO(gen))) - val out = DecoupledIO(gen) + val in = Flipped(Vec(n, Decoupled(gen))) + val out = Decoupled(gen) val chosen = Output(UInt.width(log2Up(n))) } diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 14637c9b..7c377bfb 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -62,7 +62,7 @@ object ReadyValidIO { } } -object DecoupledIO { +object Decoupled { /** Adds a ready-valid handshaking protocol to any interface. * The standard used is that the consumer uses the flipped interface. */ @@ -113,10 +113,10 @@ object Irrevocable } object EnqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen) + def apply[T<:Data](gen: T): DecoupledIO[T] = Decoupled(gen) } object DeqIO { - def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen)) + def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(Decoupled(gen)) } /** An I/O Bundle for Queues -- cgit v1.2.3 From 9c88d767e04ac25ab72380c39f30e39c83abf563 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 21 Sep 2016 15:22:54 -0700 Subject: Use correct scope for util synonyms. --- src/main/scala/chisel3/util/util.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/main/scala/chisel3/util/util.scala (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/util.scala b/src/main/scala/chisel3/util/util.scala new file mode 100644 index 00000000..812af21c --- /dev/null +++ b/src/main/scala/chisel3/util/util.scala @@ -0,0 +1,12 @@ +// See LICENSE for license details. + +package chisel3 + +package object util { + + /** Synonyms, moved from main package object - maintain scope. */ + type ValidIO[+T <: Data] = chisel3.util.Valid[T] + val ValidIO = chisel3.util.Valid + val DecoupledIO = chisel3.util.Decoupled + +} -- cgit v1.2.3 From 6eb00023fcc3ad77b98e51971f6e193ea506b9cc Mon Sep 17 00:00:00 2001 From: ducky Date: Wed, 21 Sep 2016 17:59:38 -0700 Subject: Improved scaladoc in utils and friends --- src/main/scala/chisel3/util/Cat.scala | 13 ++++--- src/main/scala/chisel3/util/CircuitMath.scala | 14 ++++---- src/main/scala/chisel3/util/Conditional.scala | 50 +++++++++++++++++++-------- src/main/scala/chisel3/util/Counter.scala | 25 +++++++++++--- src/main/scala/chisel3/util/OneHot.scala | 24 +++++++------ src/main/scala/chisel3/util/Reg.scala | 38 +++++++++++--------- 6 files changed, 105 insertions(+), 59 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Cat.scala b/src/main/scala/chisel3/util/Cat.scala index 469bf9ab..ba12a7d4 100644 --- a/src/main/scala/chisel3/util/Cat.scala +++ b/src/main/scala/chisel3/util/Cat.scala @@ -6,16 +6,15 @@ import chisel3._ import chisel3.core.SeqUtils object Cat { - /** Combine data elements together - * @param a Data to combine with - * @param r any number of other Data elements to be combined in order - * @return A UInt which is all of the bits combined together + /** Concatenates the argument data elements, in argument order, together. */ def apply[T <: Bits](a: T, r: T*): UInt = apply(a :: r.toList) - /** Combine data elements together - * @param r any number of other Data elements to be combined in order - * @return A UInt which is all of the bits combined together + /** Concatenates the data elements of the input sequence, in reverse sequence order, together. + * The first element of the sequence forms the most significant bits, while the last element + * in the sequence forms the least significant bits. + * + * Equivalent to r(0) ## r(1) ## ... ## r(n-1). */ def apply[T <: Bits](r: Seq[T]): UInt = SeqUtils.asUInt(r.reverse) } diff --git a/src/main/scala/chisel3/util/CircuitMath.scala b/src/main/scala/chisel3/util/CircuitMath.scala index a64447d9..d478e10e 100644 --- a/src/main/scala/chisel3/util/CircuitMath.scala +++ b/src/main/scala/chisel3/util/CircuitMath.scala @@ -7,13 +7,11 @@ package chisel3.util import chisel3._ -/** Compute the base-2 integer logarithm of a UInt - * @example - * {{{ data_out := Log2(data_in) }}} - * @note The result is truncated, so e.g. Log2(UInt(13)) = 3 - */ object Log2 { - /** Compute the Log2 on the least significant n bits of x */ + /** Returns the base-2 integer logarithm of the least-significant `width` bits of an UInt. + * + * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3) + */ def apply(x: Bits, width: Int): UInt = { if (width < 2) { UInt(0) @@ -30,6 +28,10 @@ object Log2 { } } + /** Returns the base-2 integer logarithm of an UInt. + * + * @note The result is truncated, so e.g. Log2(UInt(13)) === UInt(3) + */ def apply(x: Bits): UInt = apply(x, x.getWidth) private def divideAndConquerThreshold = 4 diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 6218feb0..461ff765 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -12,50 +12,72 @@ import scala.reflect.macros.blackbox._ import chisel3._ -/** This is identical to [[Chisel.when when]] with the condition inverted */ object unless { // scalastyle:ignore object.name + /** Does the same thing as [[when$ when]], but with the condition inverted. + */ def apply(c: Bool)(block: => Unit) { when (!c) { block } } } +/** Implementation details for [[switch]]. See [[switch]] and [[chisel3.util.is is]] for the + * user-facing API. + */ class SwitchContext[T <: Bits](cond: T) { def is(v: Iterable[T])(block: => Unit) { - if (!v.isEmpty) when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { block } + if (!v.isEmpty) { + when (v.map(_.asUInt === cond.asUInt).reduce(_||_)) { + block + } + } } def is(v: T)(block: => Unit) { is(Seq(v))(block) } def is(v: T, vr: T*)(block: => Unit) { is(v :: vr.toList)(block) } } -/** An object for separate cases in [[Chisel.switch switch]] - * It is equivalent to a [[Chisel.when$ when]] block comparing to the condition - * Use outside of a switch statement is illegal */ +/** Use to specify cases in a [[switch]] block, equivalent to a [[when$ when]] block comparing to + * the condition variable. + * + * @note illegal outside a [[switch]] block + * @note multiple conditions may fire simultaneously + * @note dummy implementation, a macro inside [[switch]] transforms this into the actual + * implementation + */ object is { // scalastyle:ignore object.name - // Begin deprecation of non-type-parameterized is statements. + // TODO: Begin deprecation of non-type-parameterized is statements. + /** Executes `block` if the switch condition is equal to any of the values in `v`. + */ def apply(v: Iterable[Bits])(block: => Unit) { require(false, "The 'is' keyword may not be used outside of a switch.") } + /** Executes `block` if the switch condition is equal to `v`. + */ def apply(v: Bits)(block: => Unit) { require(false, "The 'is' keyword may not be used outside of a switch.") } + /** Executes `block` if the switch condition is equal to any of the values in the argument list. + */ def apply(v: Bits, vr: Bits*)(block: => Unit) { require(false, "The 'is' keyword may not be used outside of a switch.") } } -/** Conditional logic to form a switch block +/** Conditional logic to form a switch block. See [[is$ is]] for the case API. + * * @example - * {{{ ... // default values here - * switch ( myState ) { - * is( state1 ) { - * ... // some logic here + * {{{ + * switch (myState) { + * is (state1) { + * // some logic here that runs when myState === state1 * } - * is( state2 ) { - * ... // some logic here + * is (state2) { + * // some logic here that runs when myState === state2 * } - * } }}}*/ + * } + * }}} + */ object switch { // scalastyle:ignore object.name def apply[T <: Bits](cond: T)(x: => Unit): Unit = macro impl def impl(c: Context)(cond: c.Tree)(x: c.Tree): c.Tree = { import c.universe._ diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 1c95190b..4b20158f 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -5,12 +5,14 @@ package chisel3.util import chisel3._ /** A counter module + * * @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) { require(n >= 0) val value = if (n > 1) Reg(init=UInt(0, log2Up(n))) else UInt(0) + /** Increment the counter, returning whether the counter currently is at the * maximum and will wrap. The incremented value is registered and will be * visible on the next cycle. @@ -29,14 +31,27 @@ class Counter(val n: Int) { } } -/** Counter Object - * Example Usage: - * {{{ val countOn = Bool(true) // increment counter every clock cycle - * val (myCounterValue, myCounterWrap) = Counter(countOn, n) - * when ( myCounterValue === UInt(3) ) { ... } }}}*/ object Counter { + /** Instantiate a [[Counter! counter]] with the specified number of counts. + */ def apply(n: Int): Counter = new Counter(n) + + /** Instantiate a [[Counter! counter]] with the specified number of counts and a gate. + * + * @param cond condition that controls whether the counter increments this cycle + * @param n number of counts before the counter resets + * @return tuple of the counter value and whether the counter will wrap (the value is at + * maximum and the condition is true). + * + * @example {{{ + * val countOn = Bool(true) // increment counter every clock cycle + * val (counterValue, counterWrap) = Counter(countOn, 4) + * when (counterValue === UInt(3)) { + * ... + * } + * }}} + */ def apply(cond: Bool, n: Int): (UInt, Bool) = { val c = new Counter(n) var wrap: Bool = null diff --git a/src/main/scala/chisel3/util/OneHot.scala b/src/main/scala/chisel3/util/OneHot.scala index 7e04a8d7..53ba8c3d 100644 --- a/src/main/scala/chisel3/util/OneHot.scala +++ b/src/main/scala/chisel3/util/OneHot.scala @@ -7,8 +7,12 @@ package chisel3.util import chisel3._ -/** Converts from One Hot Encoding to a UInt indicating which bit is active - * This is the inverse of [[Chisel.UIntToOH UIntToOH]]*/ +/** Returns the bit position of the sole high bit of the input bitvector. + * + * Inverse operation of [[UIntToOH]]. + * + * @note assumes exactly one high bit, results undefined otherwise + */ object OHToUInt { def apply(in: Seq[Bool]): UInt = apply(Cat(in.reverse), in.size) def apply(in: Vec[Bool]): UInt = apply(in.asUInt, in.size) @@ -26,9 +30,9 @@ object OHToUInt { } } -/** @return the bit position of the trailing 1 in the input vector - * with the assumption that multiple bits of the input bit vector can be set - * @example {{{ data_out := PriorityEncoder(data_in) }}} +/** Returns the bit position of the least-significant high bit of the input bitvector. + * + * Multiple bits may be high in the input. */ object PriorityEncoder { def apply(in: Seq[Bool]): UInt = PriorityMux(in, (0 until in.size).map(UInt(_))) @@ -37,8 +41,7 @@ object PriorityEncoder { /** Returns the one hot encoding of the input UInt. */ -object UIntToOH -{ +object UIntToOH { def apply(in: UInt, width: Int = -1): UInt = if (width == -1) { UInt(1) << in @@ -47,11 +50,10 @@ object UIntToOH } } -/** Returns a bit vector in which only the least-significant 1 bit in - the input vector, if any, is set. +/** Returns a bit vector in which only the least-significant 1 bit in the input vector, if any, + * is set. */ -object PriorityEncoderOH -{ +object PriorityEncoderOH { private def encode(in: Seq[Bool]): UInt = { val outs = Seq.tabulate(in.size)(i => UInt(BigInt(1) << i, in.size)) PriorityMux(in :+ Bool(true), outs :+ UInt(0, in.size)) diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 81de4754..80a3f43e 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -1,34 +1,40 @@ // See LICENSE for license details. -/** Variations and helpers for registers. - */ - package chisel3.util import chisel3._ object RegNext { - + /** Returns a register with the specified next and no reset initialization. + * + * Essentially a 1-cycle delayed version of the input signal. + */ def apply[T <: Data](next: T): T = Reg[T](null.asInstanceOf[T], next, null.asInstanceOf[T]) + /** Returns a register with the specified next and reset initialization. + * + * Essentially a 1-cycle delayed version of the input signal. + */ def apply[T <: Data](next: T, init: T): T = Reg[T](null.asInstanceOf[T], next, init) - } object RegInit { - + /** Returns a register pre-initialized (on reset) to the specified value. + */ def apply[T <: Data](init: T): T = Reg[T](null.asInstanceOf[T], null.asInstanceOf[T], init) - } -/** A register with an Enable signal */ -object RegEnable -{ +object RegEnable { + /** Returns a register with the specified next, update enable gate, and no reset initialization. + */ def apply[T <: Data](updateData: T, enable: Bool): T = { val r = Reg(updateData) when (enable) { r := updateData } r } + + /** Returns a register with the specified next, update enable gate, and reset initialization. + */ def apply[T <: Data](updateData: T, resetData: T, enable: Bool): T = { val r = RegInit(resetData) when (enable) { r := updateData } @@ -36,15 +42,15 @@ object RegEnable } } -/** Returns the n-cycle delayed version of the input signal. - */ object ShiftRegister { - /** @param in input to delay + /** Returns the n-cycle delayed version of the input signal. + * + * @param in input to delay * @param n number of cycles to delay - * @param en enable the shift */ - def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = - { + * @param en enable the shift + */ + def apply[T <: Data](in: T, n: Int, en: Bool = Bool(true)): T = { // The order of tests reflects the expected use cases. if (n == 1) { RegEnable(in, en) -- cgit v1.2.3 From decb2ee0f0bb8223f0b2b067b88ed90b71473a28 Mon Sep 17 00:00:00 2001 From: ducky Date: Thu, 22 Sep 2016 15:21:48 -0700 Subject: Update rest of docs --- src/main/scala/chisel3/util/Arbiter.scala | 45 ++++++++++++++++----------- src/main/scala/chisel3/util/BitPat.scala | 2 +- src/main/scala/chisel3/util/Bitwise.scala | 26 +++++++++++----- src/main/scala/chisel3/util/Conditional.scala | 5 ++- src/main/scala/chisel3/util/Decoupled.scala | 42 ++++++++++++++----------- src/main/scala/chisel3/util/Enum.scala | 36 +++++++++++++++++++-- src/main/scala/chisel3/util/LFSR.scala | 13 ++++---- src/main/scala/chisel3/util/Mux.scala | 23 +++++++------- 8 files changed, 123 insertions(+), 69 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index eb541977..58ba1188 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -7,16 +7,21 @@ package chisel3.util import chisel3._ -/** An I/O bundle for the Arbiter */ +/** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs + * (selects) at most one. + * + * @param gen data type + * @param n number of inputs + */ class ArbiterIO[T <: Data](gen: T, n: Int) extends Bundle { val in = Vec(n, Decoupled(gen)).flip val out = Decoupled(gen) val chosen = UInt(OUTPUT, log2Up(n)) } -/** Arbiter Control determining which producer has access */ -private object ArbiterCtrl -{ +/** Arbiter Control determining which producer has access + */ +private object ArbiterCtrl { def apply(request: Seq[Bool]): Seq[Bool] = request.length match { case 0 => Seq() case 1 => Seq(Bool(true)) @@ -81,25 +86,27 @@ class LockingArbiter[T <: Data](gen: T, n: Int, count: Int, needsLock: Option[T } /** Hardware module that is used to sequence n producers into 1 consumer. - Producers are chosen in round robin order. - - Example usage: - val arb = new RRArbiter(2, UInt()) - arb.io.in(0) <> producer0.io.out - arb.io.in(1) <> producer1.io.out - consumer.io.in <> arb.io.out + * Producers are chosen in round robin order. + * + * @example {{{ + * val arb = new RRArbiter(2, UInt()) + * arb.io.in(0) <> producer0.io.out + * arb.io.in(1) <> producer1.io.out + * consumer.io.in <> arb.io.out + * }}} */ class RRArbiter[T <: Data](gen:T, n: Int) extends LockingRRArbiter[T](gen, n, 1) /** Hardware module that is used to sequence n producers into 1 consumer. - Priority is given to lower producer - - Example usage: - val arb = Module(new Arbiter(2, UInt())) - arb.io.in(0) <> producer0.io.out - arb.io.in(1) <> producer1.io.out - consumer.io.in <> arb.io.out - */ + * Priority is given to lower producer. + * + * @example {{{ + * val arb = Module(new Arbiter(2, UInt())) + * arb.io.in(0) <> producer0.io.out + * arb.io.in(1) <> producer1.io.out + * consumer.io.in <> arb.io.out + * }}} + */ class Arbiter[T <: Data](gen: T, n: Int) extends Module { val io = new ArbiterIO(gen, n) diff --git a/src/main/scala/chisel3/util/BitPat.scala b/src/main/scala/chisel3/util/BitPat.scala index 26106080..6c012583 100644 --- a/src/main/scala/chisel3/util/BitPat.scala +++ b/src/main/scala/chisel3/util/BitPat.scala @@ -37,7 +37,7 @@ object BitPat { /** Creates a [[BitPat]] literal from a string. * * @param n the literal value as a string, in binary, prefixed with 'b' - * @note legal characters are '0', '1', and '?', as well as '_' as white + * @note legal characters are '0', '1', and '?', as well as '_' and white * space (which are ignored) */ def apply(n: String): BitPat = { diff --git a/src/main/scala/chisel3/util/Bitwise.scala b/src/main/scala/chisel3/util/Bitwise.scala index 6451ab14..7d5ffe09 100644 --- a/src/main/scala/chisel3/util/Bitwise.scala +++ b/src/main/scala/chisel3/util/Bitwise.scala @@ -8,9 +8,18 @@ package chisel3.util import chisel3._ import chisel3.core.SeqUtils -object FillInterleaved -{ +object FillInterleaved { + /** Creates n repetitions of each bit of x in order. + * + * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) + * For example, FillInterleaved(2, "b1000") === UInt("b11 00 00 00") + */ def apply(n: Int, in: UInt): UInt = apply(n, in.toBools) + + /** Creates n repetitions of each bit of x in order. + * + * Output data-equivalent to in(size(in)-1) (n times) ## ... ## in(1) (n times) ## in(0) (n times) + */ def apply(n: Int, in: Seq[Bool]): UInt = Cat(in.map(Fill(n, _)).reverse) } @@ -22,9 +31,11 @@ object PopCount def apply(in: Bits): UInt = apply((0 until in.getWidth).map(in(_))) } -/** Fill fans out a UInt to multiple copies */ object Fill { - /** Fan out x n times */ + /** Create n repetitions of x using a tree fanout topology. + * + * Output data-equivalent to x ## x ## ... ## x (n repetitions). + */ def apply(n: Int, x: UInt): UInt = { n match { case 0 => UInt(width=0) @@ -42,10 +53,7 @@ object Fill { } } -/** Litte/big bit endian convertion: reverse the order of the bits in a UInt. -*/ -object Reverse -{ +object Reverse { private def doit(in: UInt, length: Int): UInt = { if (length == 1) { in @@ -65,5 +73,7 @@ object Reverse Cat(doit(in(half-1,0), half), doit(in(length-1,half), length-half)) } } + /** Returns the input in bit-reversed order. Useful for little/big-endian conversion. + */ def apply(in: UInt): UInt = doit(in, in.getWidth) } diff --git a/src/main/scala/chisel3/util/Conditional.scala b/src/main/scala/chisel3/util/Conditional.scala index 461ff765..5830e014 100644 --- a/src/main/scala/chisel3/util/Conditional.scala +++ b/src/main/scala/chisel3/util/Conditional.scala @@ -65,9 +65,8 @@ object is { // scalastyle:ignore object.name } /** Conditional logic to form a switch block. See [[is$ is]] for the case API. - * - * @example - * {{{ + * + * @example {{{ * switch (myState) { * is (state1) { * // some logic here that runs when myState === state1 diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 77990777..65558aa9 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -21,10 +21,10 @@ abstract class ReadyValidIO[+T <: Data](gen: T) extends Bundle def fire(dummy: Int = 0): Bool = ready && valid } -/** A concrete subclass of ReadyValidIO signalling that the user expects a +/** A concrete subclass of ReadyValidIO signaling that the user expects a * "decoupled" interface: 'valid' indicates that the producer has * put valid data in 'bits', and 'ready' indicates that the consumer is ready - * to accept the data this cycle. No requirements are placed on the signalling + * 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) @@ -35,12 +35,12 @@ class DecoupledIO[+T <: Data](gen: T) extends ReadyValidIO[T](gen) /** This factory adds a decoupled handshaking protocol to a data bundle. */ object Decoupled { - /** Take any Data and wrap it in a DecoupledIO interface */ + /** Wraps some Data with a DecoupledIO interface. */ def apply[T <: Data](gen: T): DecoupledIO[T] = new DecoupledIO(gen) - /** Take an IrrevocableIO and cast it to a DecoupledIO. - * This cast is only safe to do in cases where the IrrevocableIO - * is being produced as an output. + /** Downconverts an IrrevocableIO output to a DecoupledIO, dropping guarantees of irrevocability. + * + * @note unsafe (and will error) on the producer (input) side of an IrrevocableIO */ def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { require(irr.bits.dir == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.") @@ -67,9 +67,10 @@ object Irrevocable { def apply[T <: Data](gen: T): IrrevocableIO[T] = new IrrevocableIO(gen) - /** Take a DecoupledIO and cast it to an IrrevocableIO. - * This cast is only safe to do in cases where the IrrevocableIO - * is being consumed as an input. + /** Upconverts a DecoupledIO input to an IrrevocableIO, allowing an IrrevocableIO to be used + * where a DecoupledIO is expected. + * + * @note unsafe (and will error) on the consumer (output) side of an DecoupledIO */ def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = { require(dec.bits.dir == INPUT, "Only safe to cast consumed Decoupled bits to Irrevocable.") @@ -156,10 +157,11 @@ class QueueIO[T <: Data](gen: T, entries: Int) extends Bundle * @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. * - * Example usage: - * {{{ val q = new Queue(UInt(), 16) - * q.io.enq <> producer.io.out - * consumer.io.in <> q.io.deq }}} + * @example {{{ + * val q = new Queue(UInt(), 16) + * q.io.enq <> producer.io.out + * consumer.io.in <> q.io.deq + * }}} */ class Queue[T <: Data](gen: T, val entries: Int, @@ -223,12 +225,16 @@ extends Module(override_reset=override_reset) { } } -/** Factory for a generic hardware queue. Required parameter 'entries' controls - * the depth of the queues. The width of the queue is determined - * from the input 'enq'. +/** Factory for a generic hardware queue. * - * Example usage: - * {{{ consumer.io.in <> Queue(producer.io.out, 16) }}} + * @param enq input (enqueue) interface to the queue, also determines width of queue elements + * @param entries depth (number of elements) of the queue + * + * @returns output (dequeue) interface from the queue + * + * @example {{{ + * consumer.io.in <> Queue(producer.io.out, 16) + * }}} */ object Queue { diff --git a/src/main/scala/chisel3/util/Enum.scala b/src/main/scala/chisel3/util/Enum.scala index 4ecc243b..55b595ee 100644 --- a/src/main/scala/chisel3/util/Enum.scala +++ b/src/main/scala/chisel3/util/Enum.scala @@ -12,12 +12,42 @@ object Enum { private def createValues[T <: Bits](nodeType: T, n: Int): Seq[T] = (0 until n).map(x => nodeType.fromInt(x, log2Up(n))) - /** create n enum values of given type */ + /** Returns n unique values of the specified type. Can be used with unpacking to define enums. + * + * @example {{{ + * val state_on :: state_off :: Nil = Enum(UInt(), 2) + * val current_state = UInt() + * switch (current_state) { + * is (state_on) { + * ... + * } + * if (state_off) { + * ... + * } + * } + * }}} + * + */ def apply[T <: Bits](nodeType: T, n: Int): List[T] = createValues(nodeType, n).toList - /** create enum values of given type and names */ + /** Returns a map of the input symbols to unique values of the specified type. + * + * @example {{{ + * val states = Enum(UInt(), 'on, 'off) + * val current_state = UInt() + * switch (current_state) { + * is (states('on)) { + * ... + * } + * if (states('off)) { + * .. + * } + * } + * }}} + */ def apply[T <: Bits](nodeType: T, l: Symbol *): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap - /** create enum values of given type and names */ + /** Returns a map of the input symbols to unique values of the specified type. + */ def apply[T <: Bits](nodeType: T, l: List[Symbol]): Map[Symbol, T] = (l zip createValues(nodeType, l.length)).toMap } diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index a30c276f..e4261c20 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -8,12 +8,13 @@ package chisel3.util import chisel3._ // scalastyle:off magic.number -/** linear feedback shift register - */ -object LFSR16 -{ - def apply(increment: Bool = Bool(true)): UInt = - { +object LFSR16 { + /** Generates a 16-bit linear feedback shift register, returning the register contents. + * May be useful for generating a pseudorandom sequence. + * + * @param increment optional control to gate when the LFSR updates. + */ + def apply(increment: Bool = Bool(true)): UInt = { val width = 16 val lfsr = Reg(init=UInt(1, width)) when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) } diff --git a/src/main/scala/chisel3/util/Mux.scala b/src/main/scala/chisel3/util/Mux.scala index 9956a7e3..245de67e 100644 --- a/src/main/scala/chisel3/util/Mux.scala +++ b/src/main/scala/chisel3/util/Mux.scala @@ -9,10 +9,11 @@ import chisel3._ import chisel3.core.SeqUtils /** Builds a Mux tree out of the input signal vector using a one hot encoded - select signal. Returns the output of the Mux tree. + * select signal. Returns the output of the Mux tree. + * + * @note results undefined if multiple select signals are simultaneously high */ -object Mux1H -{ +object Mux1H { def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) def apply[T <: Data](in: Iterable[(Bool, T)]): T = SeqUtils.oneHotMux(in) @@ -22,18 +23,17 @@ object Mux1H } /** Builds a Mux tree under the assumption that multiple select signals - can be enabled. Priority is given to the first select signal. - - Returns the output of the Mux tree. + * can be enabled. Priority is given to the first select signal. + * + * Returns the output of the Mux tree. */ -object PriorityMux -{ +object PriorityMux { def apply[T <: Data](in: Seq[(Bool, T)]): T = SeqUtils.priorityMux(in) def apply[T <: Data](sel: Seq[Bool], in: Seq[T]): T = apply(sel zip in) def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in) } -/** MuxLookup creates a cascade of n Muxs to search for a key value */ +/** Creates a cascade of n Muxs to search for a key value. */ object MuxLookup { /** @param key a key to search for * @param default a default value if nothing is found @@ -46,10 +46,11 @@ object MuxLookup { res = Mux(k === key, v, res) res } - } -/** MuxCase returns the first value that is enabled in a map of values */ +/** Given an association of values to enable signals, returns the first value with an associated + * high enable signal. + */ object MuxCase { /** @param default the default value if none are enabled * @param mapping a set of data values with associated enables -- cgit v1.2.3 From 2edfe895e4ff9f751c52904f73fe701502aa926a Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 28 Sep 2016 08:43:59 -0700 Subject: Don't use firrtlDirection for direction checks - fix #298. firrtlDirection should only be used for emitting firrtl. Any checks on the actual direction should use the bound Direction `dir`. --- src/main/scala/chisel3/util/Decoupled.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 36502862..70b191bd 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -84,7 +84,7 @@ object Decoupled * @note unsafe (and will error) on the producer (input) side of an IrrevocableIO */ def apply[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { - require(getFirrtlDirection(irr.bits) == OUTPUT, "Only safe to cast produced Irrevocable bits to Decoupled.") + require(irr.bits.flatten forall (_.dir == OUTPUT), "Only safe to cast produced Irrevocable bits to Decoupled.") val d = Wire(new DecoupledIO(irr.bits)) d.bits := irr.bits d.valid := irr.valid @@ -117,7 +117,7 @@ object Irrevocable * @note unsafe (and will error) on the consumer (output) side of an DecoupledIO */ def apply[T <: Data](dec: DecoupledIO[T]): IrrevocableIO[T] = { - require(getFirrtlDirection(dec.bits) == INPUT, "Only safe to cast consumed Decoupled bits to Irrevocable.") + require(dec.bits.flatten forall (_.dir == INPUT), "Only safe to cast consumed Decoupled bits to Irrevocable.") val i = Wire(new IrrevocableIO(dec.bits)) dec.bits := i.bits dec.valid := i.valid -- cgit v1.2.3 From eb5e5dc30019be342b7a0534b425bf33b7984ce3 Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 29 Sep 2016 11:44:09 -0700 Subject: Massive rename of CompileOptions. Massage CompileOption names in an attempt to preserve default (Strict) CompileOptions in the absence of explicit imports. NOTE: Since the default is now strict, we may encounter errors when we generate connections for clients (i.e., in Vec.do_apply() when we wire up a sequence). We should really thread the CompileOptions through the macro system so the client's implicits are used. --- src/main/scala/chisel3/util/Arbiter.scala | 2 +- src/main/scala/chisel3/util/Counter.scala | 2 +- src/main/scala/chisel3/util/Decoupled.scala | 2 +- src/main/scala/chisel3/util/LFSR.scala | 2 +- src/main/scala/chisel3/util/Reg.scala | 2 +- src/main/scala/chisel3/util/Valid.scala | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index 67e28617..adeb1b34 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.CompileOptions +//import chisel3.ExplicitCompileOptions.NotStrict /** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs * (selects) at most one. diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index 5d9b8c3c..b22cfa7b 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,7 +3,7 @@ package chisel3.util import chisel3._ -import chisel3.Strict.CompileOptions +//import chisel3.ExplicitCompileOptions.Strict /** A counter module * diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 70b191bd..947d02f8 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.CompileOptions +//import chisel3.ExplicitCompileOptions.NotStrict /** An I/O Bundle containing 'valid' and 'ready' signals that handshake * the transfer of data stored in the 'bits' subfield. diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index e3c29e79..95b4da81 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.Strict.CompileOptions +//import chisel3.ExplicitCompileOptions.Strict // scalastyle:off magic.number object LFSR16 { diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index 307812f8..fcfc9ac5 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -3,7 +3,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.CompileOptions +//import chisel3.ExplicitCompileOptions.NotStrict object RegNext { /** Returns a register with the specified next and no reset initialization. diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index ed4c3721..67be7648 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -import chisel3.NotStrict.CompileOptions +//import chisel3.ExplicitCompileOptions.NotStrict /** An Bundle containing data and a signal determining if it is valid */ class Valid[+T <: Data](gen: T) extends Bundle -- cgit v1.2.3 From 96fb6a5e2c781b20470d02eac186b1b129c20bdf Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Thu, 29 Sep 2016 14:57:42 -0700 Subject: Consolidate CompileOptions and re-enable NotStrict pending macro work. --- src/main/scala/chisel3/util/Arbiter.scala | 3 ++- src/main/scala/chisel3/util/Counter.scala | 2 +- src/main/scala/chisel3/util/Decoupled.scala | 3 ++- src/main/scala/chisel3/util/LFSR.scala | 2 +- src/main/scala/chisel3/util/Reg.scala | 3 ++- src/main/scala/chisel3/util/Valid.scala | 3 ++- 6 files changed, 10 insertions(+), 6 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/Arbiter.scala b/src/main/scala/chisel3/util/Arbiter.scala index adeb1b34..89bb644a 100644 --- a/src/main/scala/chisel3/util/Arbiter.scala +++ b/src/main/scala/chisel3/util/Arbiter.scala @@ -6,7 +6,8 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.NotStrict +// TODO: remove this once we have CompileOptions threaded through the macro system. +import chisel3.core.ExplicitCompileOptions.NotStrict /** IO bundle definition for an Arbiter, which takes some number of ready-valid inputs and outputs * (selects) at most one. diff --git a/src/main/scala/chisel3/util/Counter.scala b/src/main/scala/chisel3/util/Counter.scala index b22cfa7b..ba66d667 100644 --- a/src/main/scala/chisel3/util/Counter.scala +++ b/src/main/scala/chisel3/util/Counter.scala @@ -3,7 +3,7 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.Strict +//import chisel3.core.ExplicitCompileOptions.Strict /** A counter module * diff --git a/src/main/scala/chisel3/util/Decoupled.scala b/src/main/scala/chisel3/util/Decoupled.scala index 947d02f8..a0cbf4f7 100644 --- a/src/main/scala/chisel3/util/Decoupled.scala +++ b/src/main/scala/chisel3/util/Decoupled.scala @@ -6,7 +6,8 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.NotStrict +// TODO: remove this once we have CompileOptions threaded through the macro system. +import chisel3.core.ExplicitCompileOptions.NotStrict /** An I/O Bundle containing 'valid' and 'ready' signals that handshake * the transfer of data stored in the 'bits' subfield. diff --git a/src/main/scala/chisel3/util/LFSR.scala b/src/main/scala/chisel3/util/LFSR.scala index 95b4da81..fedbf194 100644 --- a/src/main/scala/chisel3/util/LFSR.scala +++ b/src/main/scala/chisel3/util/LFSR.scala @@ -6,7 +6,7 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.Strict +//import chisel3.core.ExplicitCompileOptions.Strict // scalastyle:off magic.number object LFSR16 { diff --git a/src/main/scala/chisel3/util/Reg.scala b/src/main/scala/chisel3/util/Reg.scala index fcfc9ac5..713a3b2e 100644 --- a/src/main/scala/chisel3/util/Reg.scala +++ b/src/main/scala/chisel3/util/Reg.scala @@ -3,7 +3,8 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.NotStrict +// TODO: remove this once we have CompileOptions threaded through the macro system. +import chisel3.core.ExplicitCompileOptions.NotStrict object RegNext { /** Returns a register with the specified next and no reset initialization. diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index 67be7648..3d153a2a 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -6,7 +6,8 @@ package chisel3.util import chisel3._ -//import chisel3.ExplicitCompileOptions.NotStrict +// TODO: remove this once we have CompileOptions threaded through the macro system. +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 -- cgit v1.2.3 From bae8e4a4d2d0ffe52fe209ccc7dc19418eee8cab Mon Sep 17 00:00:00 2001 From: Jim Lawson Date: Wed, 5 Oct 2016 17:07:45 -0700 Subject: TransitName comment change. This was originally mixed in with #199, Add Assert Data. --- src/main/scala/chisel3/util/TransitName.scala | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src/main/scala/chisel3/util') diff --git a/src/main/scala/chisel3/util/TransitName.scala b/src/main/scala/chisel3/util/TransitName.scala index ce6cb60f..a3220a13 100644 --- a/src/main/scala/chisel3/util/TransitName.scala +++ b/src/main/scala/chisel3/util/TransitName.scala @@ -5,14 +5,16 @@ package chisel3.util import chisel3._ import internal.HasId +/** + * The purpose of TransitName is to allow a library to 'move' a name + * call to a more appropriate place. + * For example, a library factory function may create a module and return + * the io. The only user-exposed field is that given IO, which can't use + * any name supplied by the user. This can add a hook so that the supplied + * name then names the Module. + * See Queue companion object for working example + */ object TransitName { - // The purpose of this is to allow a library to 'move' a name call to a more - // appropriate place. - // For example, a library factory function may create a module and return - // the io. The only user-exposed field is that given IO, which can't use - // any name supplied by the user. This can add a hook so that the supplied - // name then names the Module. - // See Queue companion object for working example def apply[T<:HasId](from: T, to: HasId): T = { from.addPostnameHook((given_name: String) => {to.suggestName(given_name)}) from -- cgit v1.2.3