1
0

don't use CAM in ReorderQueue if not necessary

This commit is contained in:
Howard Mao 2016-07-13 11:08:15 -07:00
parent 2f70136f90
commit c0dc09b3a1

View File

@ -175,34 +175,57 @@ class ReorderDequeueIO[T <: Data](dType: T, tagWidth: Int) extends Bundle {
new ReorderDequeueIO(dType, tagWidth).asInstanceOf[this.type] new ReorderDequeueIO(dType, tagWidth).asInstanceOf[this.type]
} }
class ReorderQueue[T <: Data](dType: T, tagWidth: Int, size: Int) class ReorderQueue[T <: Data](dType: T, tagWidth: Int, size: Option[Int] = None)
extends Module { extends Module {
val io = new Bundle { val io = new Bundle {
val enq = new ReorderEnqueueIO(dType, tagWidth).flip val enq = new ReorderEnqueueIO(dType, tagWidth).flip
val deq = new ReorderDequeueIO(dType, tagWidth) val deq = new ReorderDequeueIO(dType, tagWidth)
} }
val roq_data = Mem(size, dType.cloneType) val tagSpaceSize = 1 << tagWidth
val roq_tags = Reg(Vec(size, UInt(width = tagWidth))) val actualSize = size.getOrElse(tagSpaceSize)
val roq_free = Reg(init = Vec.fill(size)(Bool(true)))
val roq_enq_addr = PriorityEncoder(roq_free) if (tagSpaceSize > actualSize) {
val roq_matches = roq_tags.zip(roq_free) val roq_data = Mem(actualSize, dType)
.map { case (tag, free) => tag === io.deq.tag && !free } val roq_tags = Reg(Vec(actualSize, UInt(width = tagWidth)))
val roq_deq_addr = PriorityEncoder(roq_matches) val roq_free = Reg(init = Vec.fill(actualSize)(Bool(true)))
io.enq.ready := roq_free.reduce(_ || _) val roq_enq_addr = PriorityEncoder(roq_free)
io.deq.data := roq_data(roq_deq_addr) val roq_matches = roq_tags.zip(roq_free)
io.deq.matches := roq_matches.reduce(_ || _) .map { case (tag, free) => tag === io.deq.tag && !free }
val roq_deq_addr = PriorityEncoder(roq_matches)
when (io.enq.valid && io.enq.ready) { io.enq.ready := roq_free.reduce(_ || _)
roq_data(roq_enq_addr) := io.enq.bits.data io.deq.data := roq_data(roq_deq_addr)
roq_tags(roq_enq_addr) := io.enq.bits.tag io.deq.matches := roq_matches.reduce(_ || _)
roq_free(roq_enq_addr) := Bool(false)
}
when (io.deq.valid) { when (io.enq.valid && io.enq.ready) {
roq_free(roq_deq_addr) := Bool(true) roq_data(roq_enq_addr) := io.enq.bits.data
roq_tags(roq_enq_addr) := io.enq.bits.tag
roq_free(roq_enq_addr) := Bool(false)
}
when (io.deq.valid) {
roq_free(roq_deq_addr) := Bool(true)
}
println("Warning: inferring a CAM for ReorderQueue")
} else {
val roq_data = Mem(tagSpaceSize, dType)
val roq_free = Reg(init = Vec.fill(tagSpaceSize)(Bool(true)))
io.enq.ready := roq_free(io.enq.bits.tag)
io.deq.data := roq_data(io.deq.tag)
io.deq.matches := !roq_free(io.deq.tag)
when (io.enq.valid && io.enq.ready) {
roq_data(io.enq.bits.tag) := io.enq.bits.data
roq_free(io.enq.bits.tag) := Bool(false)
}
when (io.deq.valid) {
roq_free(io.deq.tag) := Bool(true)
}
} }
} }