Skip to content

Commit

Permalink
FIFO + TEST
Browse files Browse the repository at this point in the history
  • Loading branch information
nfrederikfhf committed Nov 27, 2020
1 parent e15e0f2 commit 2fbfbd7
Show file tree
Hide file tree
Showing 2 changed files with 137 additions and 0 deletions.
90 changes: 90 additions & 0 deletions assertion/src/main/scala/BubbleFifo.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Author: Martin Schoeberl ([email protected])
*
* A simple bubble FIFO
*
*/

import chisel3._
import chisel3.util._

/*
* On signal naming:
*
* Alter's FIFO component:
*
* data - data in, q - data out, wrreq and rdreq
* state: full and empty
*
* Xilinx's FIFO component:
* din and dout, wr_en, rd_en
* state: full and empty
*
*/

class WriterIO(size: Int) extends Bundle {
val write = Input(Bool())
val busy = Output(Bool())
val din = Input(UInt(size.W))
}

class ReaderIO(size: Int) extends Bundle {
val read = Input(Bool())
val notReady = Output(Bool())
val dout = Output(UInt(size.W))
}


/**
* A single register (=stage) to build the FIFO.
*/
class FifoRegister(size: Int) extends Module {
val io = IO(new Bundle {
val enq = new WriterIO(size)
val deq = new ReaderIO(size)
})

val empty :: full :: Nil = Enum(2)
val stateReg = RegInit(empty)
val dataReg = RegInit(0.U(size.W))

when(stateReg === empty) {
when(io.enq.write) {
stateReg := full
dataReg := io.enq.din
}
}.elsewhen(stateReg === full) {
when(io.deq.read) {
stateReg := empty
dataReg := 0.U // just to better see empty slots in the waveform
}
}.otherwise {
// There should not be an otherwise state
}

io.enq.busy := (stateReg === full)
io.deq.notReady := (stateReg === empty)
io.deq.dout := dataReg
}

/**
* This is a bubble FIFO.
*/
class BubbleFifo(size: Int, depth: Int) extends Module {
val io = IO(new Bundle {
val enq = new WriterIO(size)
val deq = new ReaderIO(size)
})

val buffers = Array.fill(depth) {
Module(new FifoRegister(size))
}
for (i <- 0 until depth - 1) {
buffers(i + 1).io.enq.din := buffers(i).io.deq.dout
buffers(i + 1).io.enq.write := ~buffers(i).io.deq.notReady
buffers(i).io.deq.read := ~buffers(i + 1).io.enq.busy
}
io.enq <> buffers(0).io.enq
io.deq <> buffers(depth - 1).io.deq
}

47 changes: 47 additions & 0 deletions assertion/src/test/scala/fifoConcurrentAssertionTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import org.scalatest._
import assertionTiming._
import chisel3._
import chiseltest._


class fifoConcurrentAssertionTest extends FlatSpec with ChiselScalatestTester with Matchers {
behavior of "The fifoConcurrentAssertionTest"

it should "signal when full" in {
test(new BubbleFifo(32, 4)) {
dut => {
val w = 0
val r = new scala.util.Random
val rand = r.nextInt(2147483647)
dut.io.deq.read.poke(false.B)
dut.io.enq.write.poke(true.B)
for (w <- 0 to 4) {
dut.io.enq.din.poke(rand.U)
dut.clock.step(1)
}
dut.io.enq.busy.expect(true.B)
}
}
}

it should "test if" in {
test(new BubbleFifo(32, 8)) {
dut => {
val w = 0
dut.io.deq.read.poke(false.B)
dut.io.enq.write.poke(true.B)
dut.io.enq.din.poke(4.U)
val t = assertEventually(dut, ()=>(dut.io.deq.dout.litValue == 4), 8, "Error")
t.join
}
}
}






}


0 comments on commit 2fbfbd7

Please sign in to comment.