2012-02-26 02:09:26 +01:00
|
|
|
package rocket
|
2011-11-09 23:52:17 +01:00
|
|
|
|
|
|
|
import Chisel._
|
2012-01-14 00:55:56 +01:00
|
|
|
import Node._
|
|
|
|
import scala.math._
|
|
|
|
|
2011-12-12 15:49:16 +01:00
|
|
|
object FillInterleaved
|
|
|
|
{
|
|
|
|
def apply(n: Int, in: Bits) =
|
|
|
|
{
|
|
|
|
var out = Fill(n, in(0))
|
2011-12-17 16:20:32 +01:00
|
|
|
for (i <- 1 until in.getWidth)
|
2011-12-12 15:49:16 +01:00
|
|
|
out = Cat(Fill(n, in(i)), out)
|
|
|
|
out
|
|
|
|
}
|
2011-12-09 09:42:43 +01:00
|
|
|
}
|
|
|
|
|
2012-02-01 22:24:28 +01:00
|
|
|
class Mux1H [T <: Data](n: Int)(gen: => T) extends Component
|
2011-12-09 09:42:43 +01:00
|
|
|
{
|
|
|
|
val io = new Bundle {
|
2012-01-18 19:28:48 +01:00
|
|
|
val sel = Vec(n) { Bool(dir = INPUT) }
|
2012-02-01 22:24:28 +01:00
|
|
|
val in = Vec(n) { gen }.asInput
|
|
|
|
val out = gen.asOutput
|
2011-12-09 09:42:43 +01:00
|
|
|
}
|
|
|
|
|
2012-03-10 05:01:47 +01:00
|
|
|
io.out := Mux1H(io.sel, io.in)
|
2011-12-09 09:42:43 +01:00
|
|
|
}
|
|
|
|
|
2012-03-01 01:45:18 +01:00
|
|
|
class ioLockingArbiter[T <: Data](n: Int)(data: => T) extends Bundle {
|
2012-06-07 03:22:56 +02:00
|
|
|
val in = Vec(n) { (new FIFOIO()) { data } }.flip
|
2012-03-02 03:23:46 +01:00
|
|
|
val lock = Vec(n) { Bool() }.asInput
|
2012-06-07 03:22:56 +02:00
|
|
|
val out = (new FIFOIO()) { data }
|
2012-03-01 01:45:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
class LockingArbiter[T <: Data](n: Int)(data: => T) extends Component {
|
|
|
|
val io = new ioLockingArbiter(n)(data)
|
2012-03-02 03:23:46 +01:00
|
|
|
val locked = Vec(n) { Reg(resetVal = Bool(false)) }
|
2012-03-11 22:17:27 +01:00
|
|
|
val any_lock_held = (locked.toBits & io.lock.toBits).orR
|
2012-05-24 19:33:15 +02:00
|
|
|
val valid_arr = Vec(n) { Bool() }
|
|
|
|
val bits_arr = Vec(n) { data }
|
2012-03-11 22:17:27 +01:00
|
|
|
for(i <- 0 until n) {
|
|
|
|
valid_arr(i) := io.in(i).valid
|
|
|
|
bits_arr(i) := io.in(i).bits
|
2012-03-02 03:23:46 +01:00
|
|
|
}
|
|
|
|
|
2012-03-11 22:17:27 +01:00
|
|
|
io.in(0).ready := Mux(any_lock_held, io.out.ready && locked(0), io.out.ready)
|
|
|
|
locked(0) := Mux(any_lock_held, locked(0), io.in(0).ready && io.lock(0))
|
|
|
|
for (i <- 1 until n) {
|
|
|
|
io.in(i).ready := Mux(any_lock_held, io.out.ready && locked(i),
|
|
|
|
!io.in(i-1).valid && io.in(i-1).ready)
|
2012-03-11 23:47:27 +01:00
|
|
|
locked(i) := Mux(any_lock_held, locked(i), io.in(i).ready && io.lock(i))
|
2012-03-11 22:17:27 +01:00
|
|
|
}
|
2012-03-01 01:45:18 +01:00
|
|
|
|
2012-03-11 22:17:27 +01:00
|
|
|
var dout = io.in(n-1).bits
|
|
|
|
for (i <- 1 until n)
|
|
|
|
dout = Mux(io.in(n-1-i).valid, io.in(n-1-i).bits, dout)
|
2012-03-01 01:45:18 +01:00
|
|
|
|
2012-03-11 22:17:27 +01:00
|
|
|
var vout = io.in(0).valid
|
|
|
|
for (i <- 1 until n)
|
|
|
|
vout = vout || io.in(i).valid
|
2012-03-01 01:45:18 +01:00
|
|
|
|
2012-03-11 22:17:27 +01:00
|
|
|
val lock_idx = PriorityEncoder(locked.toBits)
|
|
|
|
io.out.valid := Mux(any_lock_held, valid_arr(lock_idx), vout)
|
|
|
|
io.out.bits := Mux(any_lock_held, bits_arr(lock_idx), dout)
|
2012-03-01 01:45:18 +01:00
|
|
|
}
|
|
|
|
|
2012-03-01 01:13:14 +01:00
|
|
|
object PriorityEncoder
|
2011-11-09 23:52:17 +01:00
|
|
|
{
|
2012-05-03 11:29:09 +02:00
|
|
|
def doit(in: Seq[Bits], n: Int): UFix = {
|
|
|
|
if (n >= in.size-1)
|
2012-03-01 01:13:14 +01:00
|
|
|
UFix(n)
|
|
|
|
else
|
2012-05-03 11:29:09 +02:00
|
|
|
Mux(in(n), UFix(n), doit(in, n+1))
|
2011-11-09 23:52:17 +01:00
|
|
|
}
|
2012-05-03 11:29:09 +02:00
|
|
|
def apply(in: Seq[Bits]): UFix = doit(in, 0)
|
|
|
|
def apply(in: Bits): UFix = apply((0 until in.getWidth).map(in(_)))
|
2011-11-09 23:52:17 +01:00
|
|
|
}
|
2012-03-10 05:01:47 +01:00
|
|
|
|
|
|
|
object PriorityEncoderOH
|
|
|
|
{
|
2012-07-31 01:06:30 +02:00
|
|
|
def apply(in: Bits): Bits = Vec(apply((0 until in.getWidth).map(in(_)))){Bits()}.toBits
|
|
|
|
def apply(in: Seq[Bits]): Seq[Bool] = {
|
2012-03-10 05:01:47 +01:00
|
|
|
var none_hot = Bool(true)
|
2012-07-31 01:06:30 +02:00
|
|
|
val out = collection.mutable.ArrayBuffer[Bool]()
|
|
|
|
for (i <- 0 until in.size) {
|
|
|
|
out += none_hot && in(i)
|
2012-03-10 05:01:47 +01:00
|
|
|
none_hot = none_hot && !in(i)
|
|
|
|
}
|
2012-07-31 01:06:30 +02:00
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
object Counter
|
|
|
|
{
|
|
|
|
def apply(cond: Bool, n: Int) = {
|
|
|
|
val c = Reg(resetVal = UFix(0, log2Up(n)))
|
|
|
|
val wrap = c === UFix(n-1)
|
|
|
|
when (cond) {
|
|
|
|
c := Mux(Bool(!isPow2(n)) && wrap, UFix(0), c + UFix(1))
|
|
|
|
}
|
|
|
|
(c, wrap && cond)
|
2012-03-10 05:01:47 +01:00
|
|
|
}
|
|
|
|
}
|