Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port util/HellaQueue.scala to Chisel3 #3108

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/main/scala/util/HellaQueue.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,36 @@

package freechips.rocketchip.util

import Chisel._
import chisel3._
import chisel3.util._

class HellaFlowQueue[T <: Data](val entries: Int)(data: => T) extends Module {
val io = new QueueIO(data, entries)
Copy link

@yqszxx yqszxx Oct 15, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need an IO() wrapper here.

The io.count is not connected.

Copy link
Contributor Author

@CircuitCoder CircuitCoder Oct 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch!

Pending fix submitted in #3157

require(entries > 1)

val do_flow = Wire(Bool())
val do_enq = io.enq.fire() && !do_flow
val do_deq = io.deq.fire() && !do_flow
val do_enq = io.enq.fire && !do_flow
val do_deq = io.deq.fire && !do_flow

val maybe_full = Reg(init=Bool(false))
val maybe_full = RegInit(false.B)
val enq_ptr = Counter(do_enq, entries)._1
val (deq_ptr, deq_done) = Counter(do_deq, entries)
when (do_enq =/= do_deq) { maybe_full := do_enq }

val ptr_match = enq_ptr === deq_ptr
val empty = ptr_match && !maybe_full
val full = ptr_match && maybe_full
val atLeastTwo = full || enq_ptr - deq_ptr >= UInt(2)
val atLeastTwo = full || enq_ptr - deq_ptr >= 2.U
do_flow := empty && io.deq.ready

val ram = SeqMem(entries, data)
val ram = SyncReadMem(entries, data)
when (do_enq) { ram.write(enq_ptr, io.enq.bits) }

// BUG! does not hold the output of the SRAM when !ready
// ... However, HellaQueue is correct due to the pipe stage
val ren = io.deq.ready && (atLeastTwo || !io.deq.valid && !empty)
val raddr = Mux(io.deq.valid, Mux(deq_done, UInt(0), deq_ptr + UInt(1)), deq_ptr)
val ram_out_valid = Reg(next = ren)
val raddr = Mux(io.deq.valid, Mux(deq_done, 0.U, deq_ptr + 1.U), deq_ptr)
val ram_out_valid = RegNext(ren)

io.deq.valid := Mux(empty, io.enq.valid, ram_out_valid)
io.enq.ready := !full
Expand Down