diff options
| author | Schuyler Eldridge | 2019-02-18 20:05:55 -0500 |
|---|---|---|
| committer | Schuyler Eldridge | 2019-02-18 20:05:55 -0500 |
| commit | 658e7f6af7b40842f2777c5cc6968e599bd32334 (patch) | |
| tree | 97bf3350b40592e8e038554ffb9fa2ac31fd3b88 /src | |
| parent | 3fb11f2d9af403adba332c65405773a390e958aa (diff) | |
Add Scaladoc for chisel3.util.Pipe
Signed-off-by: Schuyler Eldridge <schuyler.eldridge@ibm.com>
Diffstat (limited to 'src')
| -rw-r--r-- | src/main/scala/chisel3/util/Valid.scala | 82 |
1 files changed, 74 insertions, 8 deletions
diff --git a/src/main/scala/chisel3/util/Valid.scala b/src/main/scala/chisel3/util/Valid.scala index ab7ec00f..df458927 100644 --- a/src/main/scala/chisel3/util/Valid.scala +++ b/src/main/scala/chisel3/util/Valid.scala @@ -19,7 +19,7 @@ import chisel3.internal.naming.chiselName // can't use chisel3_ version because * using the [[Valid$ Valid factory]]. * @tparam T the type of the data * @param gen some data - * @see [[Valid$ Valid factory]] for concrete examples. + * @see [[Valid$ Valid factory]] for concrete examples */ class Valid[+T <: Data](gen: T) extends Bundle { /** A bit that will be asserted when `bits` is valid */ @@ -77,18 +77,38 @@ object Valid { def apply[T <: Data](gen: T): Valid[T] = new Valid(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. +/** A factory to generate a hardware pipe. This can be used to delay [[Valid]] data by a design-time configurable number + * of cycles. * - * Example usage: + * Here, we construct three different pipes using the different provided `apply` methods and hook them up together. The + * types are explicitly specified to show that these all communicate using [[Valid]] interfaces: * {{{ - * val pipe = new Pipe(UInt()) - * pipe.io.enq <> produce.io.out - * consumer.io.in <> pipe.io.deq + * val in: Valid[UInt] = Wire(Valid(UInt(2.W))) + * + * /* A zero latency (combinational) pipe is connected to 'in' */ + * val foo: Valid[UInt] = Pipe(in.valid, in.bits, 0) + * + * /* A one-cycle pipe is connected to the output of 'foo' */ + * val bar: Valid[UInt] = Pipe(foo.valid, foo.bits) + * + * /* A two-cycle pipe is connected to the output of 'bar' */ + * val baz: Valid[UInt] = Pipe(bar, 2) * }}} + * + * @see [[Pipe Pipe class]] for an alternative API + * @see [[Valid]] interface + * @see [[Queue]] and the [[Queue$ Queue factory]] for actual queues + * @see The [[ShiftRegister$ ShiftRegister factory]] to generate a pipe without a [[Valid]] interface + * @define returnType the [[Valid]] output of the final pipeline stage */ object Pipe { + + /** Generate a pipe from an explicit valid bit and some data + * @param enqValid the valid bit (must be a hardware type) + * @param enqBits the data (must be a hardware type) + * @param latency the number of pipeline stages + * @return $returnType + */ @chiselName def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int)(implicit compileOptions: CompileOptions): Valid[T] = { if (latency == 0) { @@ -102,17 +122,63 @@ object Pipe { apply(v, b, latency-1)(compileOptions) } } + + /** Generate a one-stage pipe from an explicit valid bit and some data + * @param enqValid the valid bit (must be a hardware type) + * @param enqBits the data (must be a hardware type) + * @return $returnType + */ def apply[T <: Data](enqValid: Bool, enqBits: T)(implicit compileOptions: CompileOptions): Valid[T] = { apply(enqValid, enqBits, 1)(compileOptions) } + + /** Generate a pipe for a [[Valid]] interface + * @param enq a [[Valid]] interface (must be a hardware type) + * @param latency the number of pipeline stages + * @return $returnType + */ def apply[T <: Data](enq: Valid[T], latency: Int = 1)(implicit compileOptions: CompileOptions): Valid[T] = { apply(enq.valid, enq.bits, latency)(compileOptions) } } +/** Pipeline module generator parameterized by data type and latency. + * + * This defines a module with one input, `enq`, and one output, `deq`. The input and output are [[Valid]] interfaces + * that wrap some Chisel type, e.g., a [[UInt]] or a [[Bundle]]. This generator will then chain together a number of + * pipeline stages that all advance when the input [[Valid]] `enq` fires. The output `deq` [[Valid]] will fire only + * when valid data has made it all the way through the pipeline. + * + * As an example, to construct a 4-stage pipe of 8-bit [[UInt]]s and connect it to a producer and consumer, you can use + * the following: + * {{{ + * val foo = Module(new Pipe(UInt(8.W)), 4) + * pipe.io.enq := producer.io + * consumer.io := pipe.io.deq + * }}} + * + * If you already have the [[Valid]] input or the components of a [[Valid]] interface, it may be simpler to use the + * [[Pipe$ Pipe factory]] companion object. This, which [[Pipe]] internally utilizes, will automatically connect the + * input for you. + * + * @param gen a Chisel type + * @param latency the number of pipeline stages + * @see [[Pipe$ Pipe factory]] for an alternative API + * @see [[Valid]] interface + * @see [[Queue]] and the [[Queue$ Queue factory]] for actual queues + * @see The [[ShiftRegister$ ShiftRegister factory]] to generate a pipe without a [[Valid]] interface + */ class Pipe[T <: Data](gen: T, latency: Int = 1)(implicit compileOptions: CompileOptions) extends Module { + + /** Interface for [[Pipe]]s composed of a [[Valid]] input and [[Valid]] output + * @define notAQueue + */ class PipeIO extends Bundle { + + /** [[Valid]] input */ val enq = Input(Valid(gen)) + + /** [[Valid]] output. Data will appear here `latency` cycles after being valid at `enq`. */ val deq = Output(Valid(gen)) } |
