-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e15e0f2
commit 2fbfbd7
Showing
2 changed files
with
137 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
47
assertion/src/test/scala/fifoConcurrentAssertionTest.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
} | ||
|
||
|