blob: ac936412e323c7188e85369c39d2654c69fae9b3 [file] [log] [blame]
package common
import chisel3._
import chisel3.util._
object Slice {
def apply[T <: Data](t: T, doubleBuffered: Boolean = true,
passReady: Boolean = false, passValid: Boolean = false) = {
Module(new Slice(t, doubleBuffered, passReady, passValid))
}
}
class Slice[T <: Data](t: T, doubleBuffered: Boolean,
passReady: Boolean, passValid: Boolean) extends Module {
val io = IO(new Bundle {
val in = Flipped(Decoupled(t))
val out = Decoupled(t)
val count = Output(UInt(2.W))
val value = Output(Vec(if (doubleBuffered) 2 else 1, Valid(t)))
})
val size = if (doubleBuffered) 2 else 1
val ipos = RegInit(0.U(size.W))
val opos = RegInit(0.U(size.W))
val count = RegInit(0.U(size.W))
val mem = Reg(Vec(size, t))
val empty = ipos === opos
val bypass = if (passValid) io.in.valid && io.out.ready && empty else false.B
val ivalid = io.in.valid && io.in.ready && !bypass
val ovalid = io.out.valid && io.out.ready && !bypass
when (ivalid) {
ipos := ipos + 1.U
}
when (ovalid) {
opos := opos + 1.U
}
when (ivalid =/= ovalid) {
count := count + ivalid - ovalid
}
if (doubleBuffered) {
val full = ipos(0) === opos(0) && ipos(1) =/= opos(1)
if (passReady) {
io.in.ready := !full || io.out.ready // pass-through
} else {
io.in.ready := !full
}
when (ovalid && full) {
mem(0) := mem(1)
}
when (ivalid && !ovalid && empty ||
ivalid && ovalid && !full) {
mem(0) := io.in.bits
}
when (ivalid && !ovalid && !empty ||
ivalid && ovalid && full) {
mem(1) := io.in.bits
}
io.value(0).valid := !empty
io.value(1).valid := full
io.value(0).bits := mem(0)
io.value(1).bits := mem(1)
} else {
if (passReady) {
io.in.ready := empty || io.out.ready // pass-through
} else {
io.in.ready := empty
}
when (ivalid) {
mem(0) := io.in.bits
}
io.value(0).valid := !empty
io.value(0).bits := mem(0)
}
if (!passValid) {
io.out.valid := !empty
io.out.bits := mem(0)
} else {
io.out.valid := !empty || io.in.valid // pass-through
io.out.bits := Mux(!empty, mem(0), io.in.bits) // pass-through
}
io.count := count
}
object EmitSlice extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), false, false, false), args)
}
object EmitSlice_1 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), false, false, true), args)
}
object EmitSlice_2 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), false, true, false), args)
}
object EmitSlice_3 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), false, true, true), args)
}
object EmitSlice_4 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), true, false, false), args)
}
object EmitSlice_5 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), true, false, true), args)
}
object EmitSlice_6 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), true, true, false), args)
}
object EmitSlice_7 extends App {
(new chisel3.stage.ChiselStage).emitVerilog(new Slice(UInt(32.W), true, true, true), args)
}