2012-02-25 17:09:26 -08:00
|
|
|
package rocket
|
2011-10-25 23:02:47 -07:00
|
|
|
|
|
|
|
import Chisel._
|
|
|
|
import Node._;
|
|
|
|
|
2012-02-08 17:55:05 -08:00
|
|
|
class ioQueue[T <: Data](flushable: Boolean)(data: => T) extends Bundle
|
2011-10-25 23:02:47 -07:00
|
|
|
{
|
2012-02-08 17:55:05 -08:00
|
|
|
val flush = if (flushable) Bool(INPUT) else null
|
|
|
|
val enq = new ioDecoupled()(data)
|
|
|
|
val deq = new ioDecoupled()(data).flip
|
2011-10-25 23:02:47 -07:00
|
|
|
}
|
|
|
|
|
2012-02-29 03:08:04 -08:00
|
|
|
class queue[T <: Data](entries: Int, pipe: Boolean = false, flushable: Boolean = false)(data: => T) extends Component
|
2011-10-25 23:02:47 -07:00
|
|
|
{
|
2012-02-08 17:55:05 -08:00
|
|
|
val io = new ioQueue(flushable)(data)
|
2011-10-25 23:02:47 -07:00
|
|
|
|
2012-02-08 17:55:05 -08:00
|
|
|
val do_enq = io.enq.ready && io.enq.valid
|
|
|
|
val do_deq = io.deq.ready && io.deq.valid
|
2011-10-25 23:02:47 -07:00
|
|
|
|
2012-02-24 19:22:35 -08:00
|
|
|
var enq_ptr = UFix(0)
|
|
|
|
var deq_ptr = UFix(0)
|
|
|
|
|
|
|
|
if (entries > 1)
|
|
|
|
{
|
|
|
|
enq_ptr = Reg(resetVal = UFix(0, log2up(entries)))
|
|
|
|
deq_ptr = Reg(resetVal = UFix(0, log2up(entries)))
|
|
|
|
|
|
|
|
when (do_deq) {
|
|
|
|
deq_ptr := deq_ptr + UFix(1)
|
|
|
|
}
|
|
|
|
when (do_enq) {
|
|
|
|
enq_ptr := enq_ptr + UFix(1)
|
|
|
|
}
|
|
|
|
if (flushable) {
|
|
|
|
when (io.flush) {
|
|
|
|
deq_ptr := UFix(0)
|
|
|
|
enq_ptr := UFix(0)
|
|
|
|
}
|
|
|
|
}
|
2012-02-08 17:55:05 -08:00
|
|
|
}
|
2012-02-24 19:22:35 -08:00
|
|
|
|
|
|
|
val maybe_full = Reg(resetVal = Bool(false))
|
2012-02-08 17:55:05 -08:00
|
|
|
when (do_enq != do_deq) {
|
2012-02-11 17:20:33 -08:00
|
|
|
maybe_full := do_enq
|
|
|
|
}
|
|
|
|
if (flushable) {
|
|
|
|
when (io.flush) {
|
|
|
|
maybe_full := Bool(false)
|
|
|
|
}
|
2012-01-21 20:13:15 -08:00
|
|
|
}
|
2011-10-25 23:02:47 -07:00
|
|
|
|
2012-02-24 19:22:35 -08:00
|
|
|
io.deq.valid := maybe_full || enq_ptr != deq_ptr
|
2012-02-29 03:08:04 -08:00
|
|
|
io.enq.ready := !maybe_full || enq_ptr != deq_ptr || (if (pipe) io.deq.ready else Bool(false))
|
2012-02-11 17:20:33 -08:00
|
|
|
io.deq.bits <> Mem(entries, do_enq, enq_ptr, io.enq.bits).read(deq_ptr)
|
2011-10-25 23:02:47 -07:00
|
|
|
}
|
2012-02-29 14:21:42 -08:00
|
|
|
|
|
|
|
object Queue
|
|
|
|
{
|
|
|
|
def apply[T <: Data](enq: ioDecoupled[T], entries: Int = 2, pipe: Boolean = false) = {
|
|
|
|
val q = (new queue(entries, pipe)) { enq.bits.clone }
|
|
|
|
q.io.enq <> enq
|
|
|
|
q.io.deq
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class pipereg[T <: Data]()(data: => T) extends Component
|
|
|
|
{
|
|
|
|
val io = new Bundle {
|
|
|
|
val enq = new ioValid()(data)
|
|
|
|
val deq = new ioValid()(data).flip
|
|
|
|
}
|
|
|
|
|
|
|
|
//val bits = Reg() { io.enq.bits.clone }
|
|
|
|
//when (io.enq.valid) {
|
|
|
|
// bits := io.enq.bits
|
|
|
|
//}
|
|
|
|
|
|
|
|
io.deq.valid := Reg(io.enq.valid, resetVal = Bool(false))
|
|
|
|
io.deq.bits <> Mem(1, io.enq.valid, UFix(0), io.enq.bits).read(UFix(0))
|
|
|
|
}
|
|
|
|
|
|
|
|
object PipeReg
|
|
|
|
{
|
|
|
|
def apply[T <: Data](enq: ioValid[T]) = {
|
|
|
|
val q = (new pipereg) { enq.bits.clone }
|
|
|
|
q.io.enq <> enq
|
|
|
|
q.io.deq
|
|
|
|
}
|
|
|
|
}
|