如何将重置添加到 Queue 凿子 class
How to add reset to the Queue chisel class
我正在尝试使用凿子队列 class 并希望能够在重置时刷新它。
似乎在过去 Class 构造函数
中有一个重置选项
@deprecated("Module constructor with override _reset deprecated, use withReset", "chisel3")
def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool)
但是,正如弃用消息所暗示的那样,我应该使用 withReset。
我该怎么做?
3 年前的这个 是相似的,但答案建议使用现在已弃用的 _reset argumnet。
我设法刷新异步 fifo(Chisel 2 代码),用特殊队列重写它,如下所示:
class QueueIOFlush[T <: Data](gen: T, entries: Int) extends Bundle {
val enq = Decoupled(gen.cloneType).flip
val deq = Decoupled(gen.cloneType)
val count = UInt(OUTPUT, log2Up(entries + 1))
val flush = Bool(INPUT)
}
/** Asynchronous Fifo. Used to cross two clock domains.
*
* @param T the data to transmit
* @param entries size of fifo. The actual size will be
* arrounded in the upper 2^n (size = 1<<log2Up(entries))
* @param enq_clk clock for the writing side (input)
* @param deq_clk clock for the reading side (output)
*/
class AsyncFifoFlushable[T<:Data](gen: T,
entries: Int,
enq_clk: Clock = null,
deq_clk: Clock) extends Module(enq_clk) {
val io = new QueueIOFlush(gen, entries)
val asize = log2Up(entries)
val s1_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val s2_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val s1_rst_deq = Reg(init=Bool(false), clock=enq_clk)
val s2_rst_deq = Reg(init=Bool(false), clock=enq_clk)
val s1_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val s2_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val s1_rst_enq = Reg(init=Bool(false), clock=deq_clk)
val s2_rst_enq = Reg(init=Bool(false), clock=deq_clk)
val s1_flush = Reg(init=Bool(false), clock=enq_clk)
val s2_flush = Reg(init=Bool(false), clock=enq_clk)
val slow_flush = Reg(init=Bool(false), clock=deq_clk)
val wptr_bin = Reg(init=UInt(0, asize+1), clock=enq_clk)
val wptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val not_full = Reg(init=Bool(false), clock=enq_clk)
val wptr_bin_next = wptr_bin + (io.enq.valid & not_full)
val wptr_gray_next = (wptr_bin_next >> UInt(1)) ^ wptr_bin_next
val not_full_next = !(wptr_gray_next === Cat(~s2_rptr_gray(asize,asize-1),
s2_rptr_gray(asize-2,0)))
val rptr_bin = Reg(init=UInt(0, asize+1), clock=deq_clk)
val rptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val not_empty = Reg(init=Bool(false), clock=deq_clk)
val rptr_bin_next = rptr_bin + (io.deq.ready & not_empty)
val rptr_gray_next = (rptr_bin_next >> UInt(1)) ^ rptr_bin_next
val not_empty_next = !(rptr_gray_next === s2_wptr_gray)
s2_rptr_gray := s1_rptr_gray; s1_rptr_gray := rptr_gray
s2_rst_deq := s1_rst_deq; s1_rst_deq := enq_clk.getReset
s2_wptr_gray := s1_wptr_gray; s1_wptr_gray := wptr_gray
s2_rst_enq := s1_rst_enq; s1_rst_enq := deq_clk.getReset
s1_flush := io.flush; s2_flush := s1_flush;
/* flush read pointer (deqclk) */
slow_flush := io.flush
when(slow_flush) {
rptr_bin := UInt(0, rptr_bin.getWidth())
}.otherwise{
rptr_bin := rptr_bin_next
}
/* flush write pointer (enqclk) */
when(s2_flush) {
wptr_bin := UInt(0, wptr_bin.getWidth())
}.otherwise{
wptr_bin := wptr_bin_next
}
wptr_gray := wptr_gray_next
not_full := not_full_next && !s2_rst_deq
rptr_gray := rptr_gray_next
not_empty := not_empty_next && !s2_rst_enq
io.enq.ready := not_full
io.deq.valid := not_empty
val mem = Mem(gen, 1 << asize, clock=enq_clk)
when (io.enq.valid && io.enq.ready) {
mem(wptr_bin(asize-1,0)) := io.enq.bits
}
io.deq.bits := mem(rptr_bin(asize-1,0))
}
该弃用方法指的是 withReset
。 (Spartan) API 文档 here and the source code is located here. Additionally, there's a discussion of multiple clock domains on the Chisel3 Wiki 提供了一些示例用法。
这些方法使您能够更改代码块中使用的时钟、复位或时钟和复位。如果您想更改使用哪个重置,可以执行以下操作:
import chisel3.experimental.withReset
// ...
withReset(myReset) {
// Anything in here will be reset to myReset
}
有关更详细的示例,MultiClockSpec
测试提供了一些具体示例。参见:src/test/scala/chiselTests/MultiClockSpec.scala.
我正在尝试使用凿子队列 class 并希望能够在重置时刷新它。 似乎在过去 Class 构造函数
中有一个重置选项@deprecated("Module constructor with override _reset deprecated, use withReset", "chisel3")
def this(gen: T, entries: Int, pipe: Boolean, flow: Boolean, _reset: Bool)
但是,正如弃用消息所暗示的那样,我应该使用 withReset。
我该怎么做?
3 年前的这个
我设法刷新异步 fifo(Chisel 2 代码),用特殊队列重写它,如下所示:
class QueueIOFlush[T <: Data](gen: T, entries: Int) extends Bundle {
val enq = Decoupled(gen.cloneType).flip
val deq = Decoupled(gen.cloneType)
val count = UInt(OUTPUT, log2Up(entries + 1))
val flush = Bool(INPUT)
}
/** Asynchronous Fifo. Used to cross two clock domains.
*
* @param T the data to transmit
* @param entries size of fifo. The actual size will be
* arrounded in the upper 2^n (size = 1<<log2Up(entries))
* @param enq_clk clock for the writing side (input)
* @param deq_clk clock for the reading side (output)
*/
class AsyncFifoFlushable[T<:Data](gen: T,
entries: Int,
enq_clk: Clock = null,
deq_clk: Clock) extends Module(enq_clk) {
val io = new QueueIOFlush(gen, entries)
val asize = log2Up(entries)
val s1_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val s2_rptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val s1_rst_deq = Reg(init=Bool(false), clock=enq_clk)
val s2_rst_deq = Reg(init=Bool(false), clock=enq_clk)
val s1_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val s2_wptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val s1_rst_enq = Reg(init=Bool(false), clock=deq_clk)
val s2_rst_enq = Reg(init=Bool(false), clock=deq_clk)
val s1_flush = Reg(init=Bool(false), clock=enq_clk)
val s2_flush = Reg(init=Bool(false), clock=enq_clk)
val slow_flush = Reg(init=Bool(false), clock=deq_clk)
val wptr_bin = Reg(init=UInt(0, asize+1), clock=enq_clk)
val wptr_gray = Reg(init=UInt(0, asize+1), clock=enq_clk)
val not_full = Reg(init=Bool(false), clock=enq_clk)
val wptr_bin_next = wptr_bin + (io.enq.valid & not_full)
val wptr_gray_next = (wptr_bin_next >> UInt(1)) ^ wptr_bin_next
val not_full_next = !(wptr_gray_next === Cat(~s2_rptr_gray(asize,asize-1),
s2_rptr_gray(asize-2,0)))
val rptr_bin = Reg(init=UInt(0, asize+1), clock=deq_clk)
val rptr_gray = Reg(init=UInt(0, asize+1), clock=deq_clk)
val not_empty = Reg(init=Bool(false), clock=deq_clk)
val rptr_bin_next = rptr_bin + (io.deq.ready & not_empty)
val rptr_gray_next = (rptr_bin_next >> UInt(1)) ^ rptr_bin_next
val not_empty_next = !(rptr_gray_next === s2_wptr_gray)
s2_rptr_gray := s1_rptr_gray; s1_rptr_gray := rptr_gray
s2_rst_deq := s1_rst_deq; s1_rst_deq := enq_clk.getReset
s2_wptr_gray := s1_wptr_gray; s1_wptr_gray := wptr_gray
s2_rst_enq := s1_rst_enq; s1_rst_enq := deq_clk.getReset
s1_flush := io.flush; s2_flush := s1_flush;
/* flush read pointer (deqclk) */
slow_flush := io.flush
when(slow_flush) {
rptr_bin := UInt(0, rptr_bin.getWidth())
}.otherwise{
rptr_bin := rptr_bin_next
}
/* flush write pointer (enqclk) */
when(s2_flush) {
wptr_bin := UInt(0, wptr_bin.getWidth())
}.otherwise{
wptr_bin := wptr_bin_next
}
wptr_gray := wptr_gray_next
not_full := not_full_next && !s2_rst_deq
rptr_gray := rptr_gray_next
not_empty := not_empty_next && !s2_rst_enq
io.enq.ready := not_full
io.deq.valid := not_empty
val mem = Mem(gen, 1 << asize, clock=enq_clk)
when (io.enq.valid && io.enq.ready) {
mem(wptr_bin(asize-1,0)) := io.enq.bits
}
io.deq.bits := mem(rptr_bin(asize-1,0))
}
该弃用方法指的是 withReset
。 (Spartan) API 文档 here and the source code is located here. Additionally, there's a discussion of multiple clock domains on the Chisel3 Wiki 提供了一些示例用法。
这些方法使您能够更改代码块中使用的时钟、复位或时钟和复位。如果您想更改使用哪个重置,可以执行以下操作:
import chisel3.experimental.withReset
// ...
withReset(myReset) {
// Anything in here will be reset to myReset
}
有关更详细的示例,MultiClockSpec
测试提供了一些具体示例。参见:src/test/scala/chiselTests/MultiClockSpec.scala.