167 lines
5.9 KiB
Python
167 lines
5.9 KiB
Python
|
#
|
||
|
# This file is part of LiteX.
|
||
|
#
|
||
|
# Copyright (c) 2022 Antmicro <www.antmicro.com>
|
||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||
|
|
||
|
import unittest
|
||
|
|
||
|
from migen import *
|
||
|
|
||
|
from litex.soc.cores.clock import *
|
||
|
from litex.soc.cores.ram.xilinx_fifo_sync_macro import FIFOSyncMacro
|
||
|
|
||
|
class TestFIFOSyncMacro(unittest.TestCase):
|
||
|
def testWriteRead(self):
|
||
|
def generator(dut):
|
||
|
# Check initial status
|
||
|
yield
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
self.assertEqual((yield dut.empty), 1)
|
||
|
self.assertEqual((yield dut.almostfull), 0)
|
||
|
self.assertEqual((yield dut.full), 0)
|
||
|
|
||
|
# Load values into FIFO
|
||
|
for i in range(100):
|
||
|
yield dut.wren.eq(1)
|
||
|
yield dut.wr_d.eq(i)
|
||
|
yield
|
||
|
while (yield dut.fifo.sink.ready) == 0:
|
||
|
yield
|
||
|
yield dut.wren.eq(0)
|
||
|
yield
|
||
|
|
||
|
# Check if values are queued
|
||
|
self.assertEqual((yield dut.wrcount), 100)
|
||
|
self.assertEqual((yield dut.rdcount), 0)
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
self.assertEqual((yield dut.empty), 0)
|
||
|
self.assertEqual((yield dut.almostfull), 0)
|
||
|
self.assertEqual((yield dut.full), 0)
|
||
|
|
||
|
# Read and check values
|
||
|
for i in range(100):
|
||
|
yield dut.rden.eq(1)
|
||
|
yield
|
||
|
self.assertEqual((yield dut.rd_d), i)
|
||
|
yield dut.rden.eq(0)
|
||
|
yield
|
||
|
|
||
|
# Check if status is updated
|
||
|
self.assertEqual((yield dut.wrcount), 100)
|
||
|
self.assertEqual((yield dut.rdcount), 100)
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
self.assertEqual((yield dut.empty), 1)
|
||
|
self.assertEqual((yield dut.almostfull), 0)
|
||
|
self.assertEqual((yield dut.full), 0)
|
||
|
|
||
|
|
||
|
dut = FIFOSyncMacro("18Kb", data_width=32, almost_empty_offset=128,
|
||
|
almost_full_offset=128, toolchain="symbiflow")
|
||
|
|
||
|
run_simulation(dut, generator(dut))
|
||
|
|
||
|
def testWrRdErrors(self):
|
||
|
def generator(dut):
|
||
|
# Load values into FIFO
|
||
|
for i in range(500):
|
||
|
yield dut.wren.eq(1)
|
||
|
yield dut.wr_d.eq(i)
|
||
|
yield
|
||
|
while (yield dut.fifo.sink.ready) == 0:
|
||
|
yield
|
||
|
yield dut.wren.eq(0)
|
||
|
yield
|
||
|
|
||
|
# Check if values are queued
|
||
|
self.assertEqual((yield dut.wrcount), 500)
|
||
|
self.assertEqual((yield dut.rdcount), 0)
|
||
|
self.assertEqual((yield dut.almostempty), 0)
|
||
|
self.assertEqual((yield dut.empty), 0)
|
||
|
self.assertEqual((yield dut.almostfull), 1)
|
||
|
self.assertEqual((yield dut.full), 0)
|
||
|
self.assertEqual((yield dut.wrerr), 0)
|
||
|
self.assertEqual((yield dut.rderr), 0)
|
||
|
|
||
|
# Load to queue 511 values since the next one will overflow wrcount
|
||
|
for i in range(11):
|
||
|
yield dut.wren.eq(1)
|
||
|
yield dut.wr_d.eq(500 + i)
|
||
|
yield
|
||
|
while (yield dut.fifo.sink.ready) == 0:
|
||
|
yield
|
||
|
self.assertEqual((yield dut.wrcount), 500 + i)
|
||
|
yield dut.wren.eq(0)
|
||
|
yield
|
||
|
self.assertEqual((yield dut.wrcount), 511)
|
||
|
|
||
|
# Next load should overflow wrcount and make FIFO full
|
||
|
yield dut.wren.eq(1)
|
||
|
yield dut.wr_d.eq(511)
|
||
|
yield
|
||
|
while (yield dut.fifo.sink.ready) == 0:
|
||
|
yield
|
||
|
yield dut.wren.eq(0)
|
||
|
yield
|
||
|
self.assertEqual((yield dut.wrcount), 0)
|
||
|
self.assertEqual((yield dut.almostfull), 1)
|
||
|
self.assertEqual((yield dut.full), 1)
|
||
|
self.assertEqual((yield dut.wrerr), 0)
|
||
|
|
||
|
# Every next load should cause wrerr assert since FIFO is already full
|
||
|
yield dut.wren.eq(1)
|
||
|
yield dut.wr_d.eq(512)
|
||
|
yield
|
||
|
|
||
|
# Check if status is updated
|
||
|
self.assertEqual((yield dut.wrcount), 0)
|
||
|
self.assertEqual((yield dut.rdcount), 0)
|
||
|
self.assertEqual((yield dut.almostempty), 0)
|
||
|
self.assertEqual((yield dut.empty), 0)
|
||
|
self.assertEqual((yield dut.almostfull), 1)
|
||
|
self.assertEqual((yield dut.full), 1)
|
||
|
self.assertEqual((yield dut.wrerr), 1)
|
||
|
self.assertEqual((yield dut.rderr), 0)
|
||
|
yield dut.wren.eq(0)
|
||
|
yield
|
||
|
|
||
|
# Read values until max rdcount
|
||
|
for i in range(511):
|
||
|
yield dut.rden.eq(1)
|
||
|
yield
|
||
|
while (yield dut.fifo.source.valid) == 0:
|
||
|
yield
|
||
|
self.assertEqual((yield dut.rd_d), i)
|
||
|
yield dut.rden.eq(0)
|
||
|
yield
|
||
|
self.assertEqual((yield dut.rdcount), 511)
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
|
||
|
# Next read should make FIFO empty
|
||
|
yield dut.rden.eq(1)
|
||
|
yield
|
||
|
yield dut.rden.eq(0)
|
||
|
yield
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
self.assertEqual((yield dut.empty), 1)
|
||
|
|
||
|
# FIFO is empty so every next read should cause rderr assert
|
||
|
yield dut.rden.eq(1)
|
||
|
yield
|
||
|
|
||
|
# Check if status is updated
|
||
|
self.assertEqual((yield dut.wrcount), 0)
|
||
|
self.assertEqual((yield dut.rdcount), 0)
|
||
|
self.assertEqual((yield dut.almostempty), 1)
|
||
|
self.assertEqual((yield dut.empty), 1)
|
||
|
self.assertEqual((yield dut.almostfull), 0)
|
||
|
self.assertEqual((yield dut.full), 0)
|
||
|
self.assertEqual((yield dut.wrerr), 0)
|
||
|
self.assertEqual((yield dut.rderr), 1)
|
||
|
|
||
|
|
||
|
dut = FIFOSyncMacro("18Kb", data_width=32, almost_empty_offset=128,
|
||
|
almost_full_offset=128, toolchain="symbiflow")
|
||
|
|
||
|
run_simulation(dut, generator(dut))
|