https://mp.weixin.qq.com/s/WeFesE8k0ORxlaNfLvDzgg
流水线,用于添加延迟。
参考链接:
https://github.com/freechipsproject/chisel3/blob/master/src/main/scala/chisel3/util/Valid.scala
??
1. Pipe object提供了三个工厂方法
??
最基本的方法签名如下:
def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int)(implicit compileOptions: CompileOptions): Valid[T]
接收三个参数,返回一个Valid接口。
其中:latency为延迟的clock数,enqValid为valid位,enqBits为要输出的数据类型。
实现如下:
??
这里使用了递归调用,退出条件为latency为0。当latency为0时,不需要延时。直接把输入enqValid/enqBits输出到一个Valid类型的线。
当latency不为0时,则把enqValid和enqBits输出到一个新创建的寄存器中,以实现delay一个clock的目的,然后使用递归调用:apply(v, b, latency-1) 生成后续延时所需的寄存器。
另外两个方法基于这个方法实现:
a. 默认延时一个时钟
def apply[T <: Data](enqValid: Bool, enqBits: T)(implicit compileOptions: CompileOptions): Valid[T] = {
apply(enqValid, enqBits, 1)(compileOptions)
}
b. 延时一个Valid类型的变量
def apply[T <: Data](enq: Valid[T], latency: Int = 1)(implicit compileOptions: CompileOptions): Valid[T] = {
apply(enq.valid, enq.bits, latency)(compileOptions)
}
2. Pipe模块
Pipe模块内部定义了一个PipeIO,使用Pipe伴生对象提供的工厂方法,创建一个Valid类型的接口,用于构建Pipe模块。
??
输入接口enq是Valid类型,输出接口deq也是Valid类型,io.deq <> Pipe(io.enq, latency) 把io.enq延迟latency个时钟之后,输出到io.deq中。
PS. enq是入队的意思(enqueue), deq是出队的意思(dequeue)。
3. 附录
Valid.scala:
/** 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 { @chiselName def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int)(implicit compileOptions: CompileOptions): Valid[T] = { if (latency == 0) { val out = Wire(Valid(chiselTypeOf(enqBits))) out.valid := enqValid out.bits := enqBits out } else { val v = RegNext(enqValid, false.B) val b = RegEnable(enqBits, enqValid) apply(v, b, latency-1)(compileOptions) } } def apply[T <: Data](enqValid: Bool, enqBits: T)(implicit compileOptions: CompileOptions): Valid[T] = { apply(enqValid, enqBits, 1)(compileOptions) } def apply[T <: Data](enq: Valid[T], latency: Int = 1)(implicit compileOptions: CompileOptions): Valid[T] = { apply(enq.valid, enq.bits, latency)(compileOptions) } } class Pipe[T <: Data](gen: T, latency: Int = 1)(implicit compileOptions: CompileOptions) extends Module { class PipeIO extends Bundle { val enq = Input(Valid(gen)) val deq = Output(Valid(gen)) } val io = IO(new PipeIO) io.deq <> Pipe(io.enq, latency) }
原文地址:https://www.cnblogs.com/wjcdx/p/10116971.html