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._
|
|
|
|
|
2012-02-26 00:27:09 +01:00
|
|
|
|
2012-01-14 00:55:56 +01:00
|
|
|
object foldR
|
|
|
|
{
|
2012-02-26 00:27:09 +01:00
|
|
|
def apply[T <: Bits](x: Seq[T])(f: (T, T) => T): T =
|
|
|
|
if (x.length == 1) x(0) else f(x(0), foldR(x.slice(1, x.length))(f))
|
2012-01-14 00:55:56 +01:00
|
|
|
}
|
2011-11-09 23:52:17 +01:00
|
|
|
|
2011-12-12 15:49:16 +01:00
|
|
|
object log2up
|
|
|
|
{
|
2012-01-18 08:49:32 +01:00
|
|
|
def apply(in: Int) = if (in == 1) 1 else ceil(log(in)/log(2)).toInt
|
2011-12-12 15:49:16 +01:00
|
|
|
}
|
2011-12-09 09:42:43 +01:00
|
|
|
|
2012-01-25 01:51:30 +01:00
|
|
|
object ispow2
|
|
|
|
{
|
|
|
|
def apply(in: Int) = in > 0 && ((in & (in-1)) == 0)
|
|
|
|
}
|
|
|
|
|
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-25 01:25:36 +01:00
|
|
|
// http://aggregate.ee.engr.uky.edu/MAGIC/#Population%20Count%20%28Ones%20Count%29
|
|
|
|
// http://bits.stephan-brumme.com/countBits.html
|
|
|
|
object PopCount
|
|
|
|
{
|
|
|
|
def apply(in: Bits) =
|
|
|
|
{
|
|
|
|
require(in.width <= 32)
|
|
|
|
val w = log2up(in.width+1)
|
|
|
|
var x = in
|
|
|
|
if(in.width == 2) {
|
|
|
|
x = x - ((x >> UFix(1)) & Bits("h_5555_5555"))
|
|
|
|
} else if(in.width <= 4) {
|
|
|
|
x = x - ((x >> UFix(1)) & Bits("h_5555_5555"))
|
|
|
|
x = (((x >> UFix(2)) & Bits("h_3333_3333")) + (x & Bits("h_3333_3333")))
|
|
|
|
} else if(in.width <= 8) {
|
|
|
|
x = x - ((x >> UFix(1)) & Bits("h_5555_5555"))
|
|
|
|
x = (((x >> UFix(2)) & Bits("h_3333_3333")) + (x & Bits("h_3333_3333")))
|
|
|
|
x = ((x >> UFix(4)) + x)
|
|
|
|
} else {
|
|
|
|
// count bits of each 2-bit chunk
|
|
|
|
x = x - ((x >> UFix(1)) & Bits("h_5555_5555"))
|
|
|
|
// count bits of each 4-bit chunk
|
|
|
|
x = (((x >> UFix(2)) & Bits("h_3333_3333")) + (x & Bits("h_3333_3333")))
|
|
|
|
// count bits of each 8-bit chunk
|
|
|
|
x = ((x >> UFix(4)) + x)
|
|
|
|
// mask junk in upper bits
|
|
|
|
x = x & Bits("h_0f0f_0f0f")
|
|
|
|
// add all four 8-bit chunks
|
|
|
|
x = x + (x >> UFix(8))
|
|
|
|
x = x + (x >> UFix(16))
|
|
|
|
}
|
|
|
|
x(w-1,0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-17 16:20:32 +01:00
|
|
|
object Reverse
|
|
|
|
{
|
|
|
|
def apply(in: Bits) =
|
|
|
|
{
|
|
|
|
var out = in(in.getWidth-1)
|
|
|
|
for (i <- 1 until in.getWidth)
|
|
|
|
out = Cat(in(in.getWidth-i-1), out)
|
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-18 08:49:32 +01:00
|
|
|
object OHToUFix
|
|
|
|
{
|
|
|
|
def apply(in: Bits): UFix =
|
|
|
|
{
|
2012-01-19 02:53:26 +01:00
|
|
|
val out = MuxCase( UFix(0), (0 until in.getWidth).map( i => (in(i).toBool, UFix(i))))
|
|
|
|
out.toUFix
|
2012-01-18 08:49:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
object UFixToOH
|
|
|
|
{
|
|
|
|
def apply(in: UFix, width: Int): Bits =
|
|
|
|
{
|
2012-02-01 22:26:04 +01:00
|
|
|
(UFix(1) << in(log2up(width)-1,0))
|
2012-01-18 08:49:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-24 23:39:52 +01:00
|
|
|
object LFSR16
|
|
|
|
{
|
2012-01-25 01:51:30 +01:00
|
|
|
def apply(increment: Bool = Bool(true)) =
|
2012-01-24 23:39:52 +01:00
|
|
|
{
|
|
|
|
val width = 16
|
|
|
|
val lfsr = Reg(resetVal = UFix(1, width))
|
2012-02-12 02:20:33 +01:00
|
|
|
when (increment) { lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)).toUFix }
|
2012-01-24 23:39:52 +01:00
|
|
|
lfsr
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-15 04:11:57 +01:00
|
|
|
object ShiftRegister
|
|
|
|
{
|
|
|
|
def apply [T <: Data](n: Int, in: T): T =
|
|
|
|
if (n > 0) Reg(apply(n-1, in)) else in
|
|
|
|
}
|
|
|
|
|
2012-02-01 22:24:28 +01:00
|
|
|
object Mux1H
|
|
|
|
{
|
|
|
|
//TODO: cloning in(0) is unsafe if other elements have different widths, but
|
|
|
|
//is that even allowable?
|
|
|
|
def apply [T <: Data](n: Int, sel: Vec[Bool], in: Vec[T]): T = {
|
|
|
|
MuxCase(in(0), (0 until n).map( i => (sel(i), in(i))))
|
|
|
|
// val mux = (new Mux1H(n)){ in(0).clone }
|
|
|
|
// mux.io.sel <> sel
|
|
|
|
// mux.io.in <> in
|
|
|
|
// mux.io.out.asInstanceOf[T]
|
|
|
|
}
|
|
|
|
|
|
|
|
def apply [T <: Data](n: Int, sel: Seq[Bool], in: Vec[T]): T = {
|
|
|
|
MuxCase(in(0), (0 until n).map( i => (sel(i), in(i))))
|
|
|
|
// val mux = (new Mux1H(n)){ in(0).clone }
|
|
|
|
// for(i <- 0 until n) {
|
|
|
|
// mux.io.sel(i) := sel(i)
|
|
|
|
// }
|
|
|
|
// mux.io.in <> in.asOutput
|
|
|
|
// mux.io.out.asInstanceOf[T]
|
|
|
|
}
|
|
|
|
|
|
|
|
def apply [T <: Data](n: Int, sel: Bits, in: Vec[T]): T = {
|
|
|
|
MuxCase(in(0), (0 until n).map( i => (sel(i).toBool, in(i))))
|
|
|
|
// val mux = (new Mux1H(n)){ in(0).clone }
|
|
|
|
// for(i <- 0 until n) {
|
|
|
|
// mux.io.sel(i) := sel(i).toBool
|
|
|
|
// }
|
|
|
|
// mux.io.in := in
|
|
|
|
// mux.io.out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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-02-01 22:24:28 +01:00
|
|
|
if (n > 2) {
|
|
|
|
var out = io.in(0).toBits & Fill(gen.getWidth, io.sel(0))
|
2011-12-12 15:49:16 +01:00
|
|
|
for (i <- 1 to n-1)
|
2012-02-01 22:24:28 +01:00
|
|
|
out = out | (io.in(i).toBits & Fill(gen.getWidth, io.sel(i)))
|
2011-12-12 15:49:16 +01:00
|
|
|
io.out := out
|
2012-02-01 22:24:28 +01:00
|
|
|
} else if (n == 2) {
|
|
|
|
io.out := Mux(io.sel(1), io.in(1), io.in(0))
|
2011-12-09 09:42:43 +01:00
|
|
|
} else {
|
|
|
|
io.out := io.in(0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-02-01 22:24:28 +01:00
|
|
|
|
2012-02-29 21:29:33 +01:00
|
|
|
class ioDecoupled[+T <: Data]()(data: => T) extends Bundle
|
2011-12-09 09:42:43 +01:00
|
|
|
{
|
2012-01-18 19:28:48 +01:00
|
|
|
val valid = Bool(INPUT)
|
|
|
|
val ready = Bool(OUTPUT)
|
2011-12-09 09:42:43 +01:00
|
|
|
val bits = data.asInput
|
|
|
|
}
|
|
|
|
|
2012-02-29 12:08:04 +01:00
|
|
|
class ioValid[T <: Data]()(data: => T) extends Bundle
|
|
|
|
{
|
|
|
|
val valid = Bool(INPUT)
|
|
|
|
val bits = data.asInput
|
|
|
|
}
|
|
|
|
|
2011-12-09 09:42:43 +01:00
|
|
|
class ioArbiter[T <: Data](n: Int)(data: => T) extends Bundle {
|
|
|
|
val in = Vec(n) { (new ioDecoupled()) { data } }
|
|
|
|
val out = (new ioDecoupled()) { data }.flip()
|
|
|
|
}
|
|
|
|
|
|
|
|
class Arbiter[T <: Data](n: Int)(data: => T) extends Component {
|
|
|
|
val io = new ioArbiter(n)(data)
|
|
|
|
|
|
|
|
io.in(0).ready := io.out.ready
|
|
|
|
for (i <- 1 to n-1) {
|
|
|
|
io.in(i).ready := !io.in(i-1).valid && io.in(i-1).ready
|
|
|
|
}
|
|
|
|
|
2011-12-12 15:49:16 +01:00
|
|
|
var dout = io.in(n-1).bits
|
|
|
|
for (i <- 1 to n-1)
|
|
|
|
dout = Mux(io.in(n-1-i).valid, io.in(n-1-i).bits, dout)
|
2011-12-09 09:42:43 +01:00
|
|
|
|
2011-12-21 07:08:27 +01:00
|
|
|
var vout = io.in(0).valid
|
|
|
|
for (i <- 1 to n-1)
|
|
|
|
vout = vout || io.in(i).valid
|
2011-12-09 09:42:43 +01:00
|
|
|
|
2012-01-23 18:51:35 +01:00
|
|
|
vout <> io.out.valid
|
|
|
|
dout <> io.out.bits
|
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 {
|
|
|
|
val in = Vec(n) { (new ioDecoupled()) { data } }
|
2012-03-02 03:23:46 +01:00
|
|
|
val lock = Vec(n) { Bool() }.asInput
|
2012-03-01 01:45:18 +01:00
|
|
|
val out = (new ioDecoupled()) { data }.flip()
|
|
|
|
}
|
|
|
|
|
|
|
|
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-01 10:19:09 +01:00
|
|
|
var dout = io.in(0).bits
|
|
|
|
var vout = Bool(false)
|
2012-03-01 01:45:18 +01:00
|
|
|
|
2012-03-02 03:23:46 +01:00
|
|
|
for (i <- 0 until n) {
|
|
|
|
io.in(i).ready := io.out.ready
|
|
|
|
}
|
|
|
|
|
|
|
|
val any_lock_held = (locked.toBits & io.lock.toBits).orR
|
2012-03-01 10:19:09 +01:00
|
|
|
when(any_lock_held) {
|
|
|
|
vout = io.in(0).valid && locked(0)
|
2012-03-01 01:45:18 +01:00
|
|
|
for (i <- 0 until n) {
|
|
|
|
io.in(i).ready := io.out.ready && locked(i)
|
2012-03-01 10:19:09 +01:00
|
|
|
dout = Mux(locked(i), io.in(i).bits, dout)
|
|
|
|
vout = vout || io.in(i).valid && locked(i)
|
2012-03-01 01:45:18 +01:00
|
|
|
}
|
|
|
|
} .otherwise {
|
|
|
|
io.in(0).ready := io.out.ready
|
2012-03-02 03:23:46 +01:00
|
|
|
locked(0) := io.out.ready && io.lock(0)
|
2012-03-01 01:45:18 +01:00
|
|
|
for (i <- 1 until n) {
|
|
|
|
io.in(i).ready := !io.in(i-1).valid && io.in(i-1).ready
|
2012-03-02 03:23:46 +01:00
|
|
|
locked(i) := !io.in(i-1).valid && io.in(i-1).ready && io.lock(i)
|
2012-03-01 01:45:18 +01:00
|
|
|
}
|
|
|
|
|
2012-03-01 10:19:09 +01:00
|
|
|
dout = io.in(n-1).bits
|
2012-03-01 01:45:18 +01:00
|
|
|
for (i <- 1 until n)
|
|
|
|
dout = Mux(io.in(n-1-i).valid, io.in(n-1-i).bits, dout)
|
|
|
|
|
2012-03-01 10:19:09 +01:00
|
|
|
vout = io.in(0).valid
|
2012-03-01 01:45:18 +01:00
|
|
|
for (i <- 1 until n)
|
|
|
|
vout = vout || io.in(i).valid
|
|
|
|
}
|
|
|
|
|
|
|
|
vout <> io.out.valid
|
|
|
|
dout <> io.out.bits
|
|
|
|
}
|
|
|
|
|
2012-03-01 01:13:14 +01:00
|
|
|
object PriorityEncoder
|
2011-11-09 23:52:17 +01:00
|
|
|
{
|
2012-03-01 01:13:14 +01:00
|
|
|
def apply(in: Bits, n: Int = 0): UFix = {
|
|
|
|
if (n >= in.getWidth-1)
|
|
|
|
UFix(n)
|
|
|
|
else
|
|
|
|
Mux(in(n), UFix(n), PriorityEncoder(in, n+1))
|
2011-11-09 23:52:17 +01:00
|
|
|
}
|
|
|
|
}
|