factored out common stuff to ChiselUtil
This commit is contained in:
		@@ -3,99 +3,6 @@ package rocket
 | 
				
			|||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import Node._;
 | 
					import Node._;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ioQueue[T <: Data](entries: Int)(data: => T) extends Bundle
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  val enq   = new FIFOIO()(data).flip
 | 
					 | 
				
			||||||
  val deq   = new FIFOIO()(data)
 | 
					 | 
				
			||||||
  val count = UFix(OUTPUT, log2Up(entries+1))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Queue[T <: Data](val entries: Int, pipe: Boolean = false, flow: Boolean = false, resetSignal: Bool = null)(data: => T) extends Component(resetSignal)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  val io = new ioQueue(entries)(data)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val do_flow = Bool()
 | 
					 | 
				
			||||||
  val do_enq = io.enq.ready && io.enq.valid && !do_flow
 | 
					 | 
				
			||||||
  val do_deq = io.deq.ready && io.deq.valid && !do_flow
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var enq_ptr = UFix(0)
 | 
					 | 
				
			||||||
  var deq_ptr = UFix(0)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (entries > 1)
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    enq_ptr = Counter(do_enq, entries)._1
 | 
					 | 
				
			||||||
    deq_ptr = Counter(do_deq, entries)._1
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val maybe_full = Reg(resetVal = Bool(false))
 | 
					 | 
				
			||||||
  when (do_enq != do_deq) {
 | 
					 | 
				
			||||||
    maybe_full := do_enq
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val ram = Mem(entries) { data }
 | 
					 | 
				
			||||||
  when (do_enq) { ram(enq_ptr) := io.enq.bits }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val ptr_match = enq_ptr === deq_ptr
 | 
					 | 
				
			||||||
  val empty = ptr_match && !maybe_full
 | 
					 | 
				
			||||||
  val full = ptr_match && maybe_full
 | 
					 | 
				
			||||||
  val maybe_flow = Bool(flow) && empty
 | 
					 | 
				
			||||||
  do_flow := maybe_flow && io.deq.ready
 | 
					 | 
				
			||||||
  io.deq.valid :=  !empty || Bool(flow) && io.enq.valid
 | 
					 | 
				
			||||||
  io.enq.ready := !full || Bool(pipe) && io.deq.ready
 | 
					 | 
				
			||||||
  io.deq.bits := Mux(maybe_flow, io.enq.bits, ram(deq_ptr))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  val ptr_diff = enq_ptr - deq_ptr
 | 
					 | 
				
			||||||
  if (isPow2(entries))
 | 
					 | 
				
			||||||
    io.count := Cat(maybe_full && ptr_match, ptr_diff).toUFix
 | 
					 | 
				
			||||||
  else
 | 
					 | 
				
			||||||
    io.count := Mux(ptr_match, Mux(maybe_full, UFix(entries), UFix(0)), Mux(deq_ptr > enq_ptr, UFix(entries) + ptr_diff, ptr_diff))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object Queue
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply[T <: Data](enq: FIFOIO[T], entries: Int = 2, pipe: Boolean = false) = {
 | 
					 | 
				
			||||||
    val q = (new Queue(entries, pipe)) { enq.bits.clone }
 | 
					 | 
				
			||||||
    q.io.enq.valid := enq.valid // not using <> so that override is allowed
 | 
					 | 
				
			||||||
    q.io.enq.bits := enq.bits
 | 
					 | 
				
			||||||
    enq.ready := q.io.enq.ready
 | 
					 | 
				
			||||||
    q.io.deq
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Pipe[T <: Data](latency: Int = 1)(data: => T) extends Component
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  val io = new Bundle {
 | 
					 | 
				
			||||||
    val enq = new PipeIO()(data).flip
 | 
					 | 
				
			||||||
    val deq = new PipeIO()(data)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var bits: T = io.enq.bits
 | 
					 | 
				
			||||||
  var valid: Bool = io.enq.valid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (i <- 0 until latency) {
 | 
					 | 
				
			||||||
    val reg_bits = Reg() { io.enq.bits.clone }
 | 
					 | 
				
			||||||
    val reg_valid = Reg(valid, resetVal = Bool(false))
 | 
					 | 
				
			||||||
    when (valid) { reg_bits := bits }
 | 
					 | 
				
			||||||
    valid = reg_valid
 | 
					 | 
				
			||||||
    bits = reg_bits
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  io.deq.valid := valid
 | 
					 | 
				
			||||||
  io.deq.bits := bits
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object Pipe
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply[T <: Data](enqValid: Bool, enqBits: T, latency: Int): PipeIO[T] = {
 | 
					 | 
				
			||||||
    val q = (new Pipe(latency)) { enqBits.clone }
 | 
					 | 
				
			||||||
    q.io.enq.valid := enqValid
 | 
					 | 
				
			||||||
    q.io.enq.bits := enqBits
 | 
					 | 
				
			||||||
    q.io.deq
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  def apply[T <: Data](enqValid: Bool, enqBits: T): PipeIO[T] = apply(enqValid, enqBits, 1)
 | 
					 | 
				
			||||||
  def apply[T <: Data](enq: PipeIO[T], latency: Int = 1): PipeIO[T] = apply(enq.valid, enq.bits, latency)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class SkidBuffer[T <: Data](resetSignal: Bool = null)(data: => T) extends Component(resetSignal)
 | 
					class SkidBuffer[T <: Data](resetSignal: Bool = null)(data: => T) extends Component(resetSignal)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  val io = new Bundle {
 | 
					  val io = new Bundle {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@ package rocket
 | 
				
			|||||||
import Chisel._
 | 
					import Chisel._
 | 
				
			||||||
import Node._;
 | 
					import Node._;
 | 
				
			||||||
import Constants._;
 | 
					import Constants._;
 | 
				
			||||||
import collection.mutable._
 | 
					import collection.mutable.ArrayBuffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Top extends Component
 | 
					class Top extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,17 +4,6 @@ import Chisel._
 | 
				
			|||||||
import Node._
 | 
					import Node._
 | 
				
			||||||
import scala.math._
 | 
					import scala.math._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
object FillInterleaved
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply(n: Int, in: Bits) =
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    var out = Fill(n, in(0))
 | 
					 | 
				
			||||||
    for (i <- 1 until in.getWidth)
 | 
					 | 
				
			||||||
      out = Cat(Fill(n, in(i)), out)
 | 
					 | 
				
			||||||
    out
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Mux1H [T <: Data](n: Int)(gen: => T) extends Component
 | 
					class Mux1H [T <: Data](n: Int)(gen: => T) extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  val io = new Bundle {
 | 
					  val io = new Bundle {
 | 
				
			||||||
@@ -25,84 +14,3 @@ class Mux1H [T <: Data](n: Int)(gen: => T) extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  io.out := Mux1H(io.sel, io.in)
 | 
					  io.out := Mux1H(io.sel, io.in)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
class ioLockingArbiter[T <: Data](n: Int)(data: => T) extends Bundle {
 | 
					 | 
				
			||||||
  val in   = Vec(n) { (new FIFOIO()) { data } }.flip
 | 
					 | 
				
			||||||
  val lock = Vec(n) { Bool() }.asInput
 | 
					 | 
				
			||||||
  val out  = (new FIFOIO()) { data }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class LockingArbiter[T <: Data](n: Int)(data: => T) extends Component {
 | 
					 | 
				
			||||||
  val io = new ioLockingArbiter(n)(data)
 | 
					 | 
				
			||||||
  val locked = Vec(n) { Reg(resetVal = Bool(false)) }
 | 
					 | 
				
			||||||
  val any_lock_held = (locked.toBits & io.lock.toBits).orR
 | 
					 | 
				
			||||||
  val valid_arr = Vec(n) { Bool() } 
 | 
					 | 
				
			||||||
  val bits_arr = Vec(n) { data } 
 | 
					 | 
				
			||||||
  for(i <- 0 until n) {
 | 
					 | 
				
			||||||
    valid_arr(i) := io.in(i).valid
 | 
					 | 
				
			||||||
    bits_arr(i) := io.in(i).bits
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
    locked(i) := Mux(any_lock_held, locked(i), io.in(i).ready && io.lock(i))
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  var vout = io.in(0).valid
 | 
					 | 
				
			||||||
  for (i <- 1 until n)
 | 
					 | 
				
			||||||
    vout = vout || io.in(i).valid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  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)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object PriorityMux
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply[T <: Data](sel: Seq[Bits], in: Seq[T]): T = {
 | 
					 | 
				
			||||||
    if (in.size == 1)
 | 
					 | 
				
			||||||
      in.head
 | 
					 | 
				
			||||||
    else
 | 
					 | 
				
			||||||
      Mux(sel.head, in.head, apply(sel.tail, in.tail))
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  def apply[T <: Data](sel: Bits, in: Seq[T]): T = apply((0 until in.size).map(sel(_)), in)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object PriorityEncoder
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply(in: Seq[Bits]): UFix = PriorityMux(in, (0 until in.size).map(UFix(_)))
 | 
					 | 
				
			||||||
  def apply(in: Bits): UFix = apply((0 until in.getWidth).map(in(_)))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
object PriorityEncoderOH
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
  def apply(in: Bits): Bits = Vec(apply((0 until in.getWidth).map(in(_)))){Bool()}.toBits
 | 
					 | 
				
			||||||
  def apply(in: Seq[Bits]): Seq[Bool] = {
 | 
					 | 
				
			||||||
    var none_hot = Bool(true)
 | 
					 | 
				
			||||||
    val out = collection.mutable.ArrayBuffer[Bool]()
 | 
					 | 
				
			||||||
    for (i <- 0 until in.size) {
 | 
					 | 
				
			||||||
      out += none_hot && in(i)
 | 
					 | 
				
			||||||
      none_hot = none_hot && !in(i)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    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)
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user