1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
// See LICENSE for license details.
/** Wrappers for valid interfaces and associated circuit generators using them.
*/
package chisel3.util
import chisel3._
/** An Bundle containing data and a signal determining if it is valid */
class Valid[+T <: Data](gen: T) extends Bundle
{
val valid = Output(Bool())
val bits = Output(gen.chiselCloneType)
def fire(dummy: Int = 0): Bool = valid
override def cloneType: this.type = Valid(gen).asInstanceOf[this.type]
}
/** Adds a valid protocol to any interface */
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.
Example usage:
val pipe = new Pipe(UInt())
pipe.io.enq <> produce.io.out
consumer.io.in <> pipe.io.deq
*/
object Pipe
{
def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): Valid[T] = {
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): Valid[T] = apply(enqValid, enqBits, 1)
def apply[T <: Data](enq: Valid[T], latency: Int = 1): Valid[T] = apply(enq.valid, enq.bits, latency)
}
class Pipe[T <: Data](gen: T, latency: Int = 1) extends Module
{
val io = IO(new Bundle {
val enq = Input(Valid(gen))
val deq = Output(Valid(gen))
})
io.deq <> Pipe(io.enq, latency)
}
|