summaryrefslogtreecommitdiff
path: root/src/main/scala/Chisel/util/Decoupled.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/Chisel/util/Decoupled.scala')
-rw-r--r--src/main/scala/Chisel/util/Decoupled.scala113
1 files changed, 52 insertions, 61 deletions
diff --git a/src/main/scala/Chisel/util/Decoupled.scala b/src/main/scala/Chisel/util/Decoupled.scala
index 8e045855..66b348e0 100644
--- a/src/main/scala/Chisel/util/Decoupled.scala
+++ b/src/main/scala/Chisel/util/Decoupled.scala
@@ -8,71 +8,62 @@ 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]
+ val ready = Input(Bool())
+ val valid = Output(Bool())
+ val bits = Output(gen.newType)
+ override protected def cloneType: this.type = 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 {
+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)
-}
-/** 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 }
+ implicit class AddMethodsToDecoupled[T<:Data](val target: DecoupledIO[T]) extends AnyVal {
+ def firing: 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.
+ * @return dat.
+ */
+ def enq(dat: T): T = {
+ target.valid := true.asBool
+ target.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]; }
-}
+ /** Indicate no enqueue occurs. Valid is set to false, and all bits are set to zero.
+ */
+ def noenq(): Unit = {
+ target.valid := false.asBool
+ target.bits := target.bits.fromBits(0.asUInt)
+ }
-/** 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 }
+ /** 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(): T = {
+ target.ready := true.asBool
+ target.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)
+ /** Indicate no dequeue occurs. Ready is set to false
+ */
+ def nodeq(): Unit = {
+ target.ready := false.asBool
+ }
}
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
+object EnqIO {
+ def apply[T<:Data](gen: T): DecoupledIO[T] = Flipped(DecoupledIO(gen))
+}
+object DeqIO {
+ def apply[T<:Data](gen: T): DecoupledIO[T] = DecoupledIO(gen)
}
/** An I/O Bundle for Queues
@@ -81,11 +72,11 @@ class DecoupledIOC[+T <: Data](gen: T) extends Bundle
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()
+ val enq = EnqIO(gen)
/** I/O to enqueue data, is [[Chisel.DecoupledIO]]*/
- val deq = Decoupled(gen.cloneType)
+ val deq = DeqIO(gen)
/** The current amount of data in the queue */
- val count = UInt(OUTPUT, log2Up(entries + 1))
+ val count = Output(UInt(log2Up(entries + 1)))
}
/** A hardware module implementing a Queue
@@ -109,7 +100,7 @@ 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 io = IO(new QueueIO(gen, entries))
val ram = Mem(entries, gen)
val enq_ptr = Counter(entries)
@@ -119,8 +110,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.fire())
- val do_deq = Wire(init=io.deq.fire())
+ val do_enq = Wire(init=io.enq.firing)
+ val do_deq = Wire(init=io.deq.firing)
when (do_enq) {
ram(enq_ptr.value) := io.enq.bits
@@ -167,7 +158,7 @@ extends Module(override_reset=override_reset) {
from the inputs.
Example usage:
- {{{ val q = Queue(Decoupled(UInt()), 16)
+ {{{ val q = Queue(DecoupledIO(UInt()), 16)
q.io.enq <> producer.io.out
consumer.io.in <> q.io.deq }}}
*/