@@ -364,6 +364,7 @@ async def testbench_write(ctx):
364364 await ctx .tick ("write" )
365365 ctx .set (fifo .w_en , 0 )
366366 await ctx .tick ("write" )
367+
367368 self .assertEqual (ctx .get (fifo .w_level ), expected_level )
368369 ctx .set (write_done , 1 )
369370
@@ -405,3 +406,138 @@ def test_async_buffered_fifo_level_full(self):
405406 def test_async_buffered_fifo_level_empty (self ):
406407 fifo = AsyncFIFOBuffered (width = 32 , depth = 9 , r_domain = "read" , w_domain = "write" )
407408 self .check_async_fifo_level (fifo , fill_in = 0 , expected_level = 0 , read = True )
409+
410+ def check_async_fifo_reset (self , fifo , r_period , w_period , r_phase = None , w_phase = None ):
411+ write_rst = Signal ()
412+ read_non_empty_1 = Signal ()
413+ read_non_empty_2 = Signal ()
414+ reset_write_reset = Signal ()
415+
416+ m = Module ()
417+ m .submodules .fifo = fifo
418+ m .d .comb += ResetSignal ("write" ).eq (write_rst )
419+
420+ async def testbench_write (ctx ):
421+ # First refill ========================================================================
422+
423+ # - wait until the FIFO read interface comes out of reset:
424+ await ctx .tick ("write" ).until (~ fifo .r_rst )
425+
426+ # - fill the FIFO:
427+ ctx .set (fifo .w_en , 1 )
428+ for i in range (fifo .depth ):
429+ ctx .set (fifo .w_data , 0x5a5a5a00 | i )
430+ await ctx .tick ("write" ).until (fifo .w_rdy )
431+ ctx .set (fifo .w_en , 0 )
432+
433+ # - wait until the FIFO is readable:
434+ await ctx .tick ("write" ).until (read_non_empty_1 )
435+
436+ # Back-to-back reset + refill =========================================================
437+
438+ # - reset the write domain:
439+ ctx .set (write_rst , 1 )
440+ await ctx .tick ("write" )
441+ ctx .set (write_rst , 0 )
442+ self .assertEqual (ctx .get (fifo .w_rdy ), 1 )
443+
444+ # - fill the FIFO:
445+ ctx .set (fifo .w_en , 1 )
446+ for i in range (fifo .depth ):
447+ ctx .set (fifo .w_data , 0xa5a5a500 | i )
448+ await ctx .tick ("write" ).until (fifo .w_rdy )
449+ ctx .set (fifo .w_en , 0 )
450+
451+ # - wait until the FIFO is readable:
452+ await ctx .tick ("write" ).until (read_non_empty_2 )
453+
454+ # Back-to-back reset + write + reset ==================================================
455+
456+ # - reset the write domain:
457+ ctx .set (write_rst , 1 )
458+ await ctx .tick ("write" )
459+ ctx .set (write_rst , 0 )
460+ self .assertEqual (ctx .get (fifo .w_rdy ), 1 )
461+
462+ # - write to the FIFO:
463+ ctx .set (fifo .w_en , 1 )
464+ ctx .set (fifo .w_data , 0xc3c3c3c3 )
465+ await ctx .tick ("write" )
466+ ctx .set (fifo .w_en , 0 )
467+
468+ # - reset the write domain:
469+ ctx .set (write_rst , 1 )
470+ await ctx .tick ("write" )
471+ ctx .set (write_rst , 0 )
472+ await ctx .tick ("write" )
473+ ctx .set (reset_write_reset , 1 )
474+
475+ async def testbench_read (ctx ):
476+ # First refill ========================================================================
477+
478+ # - wait until the FIFO read interface comes out of reset:
479+ self .assertEqual (ctx .get (fifo .r_rst ), 1 )
480+ await ctx .tick ("read" ).until (~ fifo .r_rst )
481+
482+ # - wait until the FIFO is readable:
483+ self .assertEqual (ctx .get (fifo .r_rdy ), 0 )
484+ fifo_r_data , = await ctx .tick ("read" ).sample (fifo .r_data ).until (fifo .r_rdy )
485+ ctx .set (read_non_empty_1 , 1 )
486+ self .assertEqual (fifo_r_data , 0x5a5a5a00 )
487+
488+ # Back-to-back reset + refill =========================================================
489+
490+ # - wait until the FIFO read interface comes out of reset:
491+ await ctx .posedge (fifo .r_rst )
492+ await ctx .tick ("read" ).until (~ fifo .r_rst )
493+
494+ # - wait until the FIFO is readable:
495+ fifo_r_data , = await ctx .tick ("read" ).sample (fifo .r_data ).until (fifo .r_rdy )
496+ ctx .set (read_non_empty_2 , 1 )
497+ self .assertEqual (fifo_r_data , 0xa5a5a500 )
498+
499+ # Back-to-back reset + write + reset ==================================================
500+
501+ # - wait until the FIFO read interface comes out of reset:
502+ await ctx .tick ("read" ).until (reset_write_reset & ~ fifo .r_rst )
503+ self .assertEqual (ctx .get (fifo .r_rdy ), 0 )
504+
505+ simulator = Simulator (m )
506+ simulator .add_clock (w_period , phase = w_phase , domain = "write" )
507+ simulator .add_clock (r_period , phase = r_phase , domain = "read" )
508+ simulator .add_testbench (testbench_write )
509+ simulator .add_testbench (testbench_read )
510+ with simulator .write_vcd ("test.vcd" ):
511+ simulator .run ()
512+
513+ def test_async_fifo_reset_same_clk (self ):
514+ fifo = AsyncFIFO (width = 32 , depth = 2 , r_domain = "read" , w_domain = "write" )
515+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 10e-9 )
516+
517+ def test_async_fifo_reset_phase_180deg (self ):
518+ fifo = AsyncFIFO (width = 32 , depth = 2 , r_domain = "read" , w_domain = "write" )
519+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 10e-9 , r_phase = 0.0 , w_phase = 5e-9 )
520+
521+ def test_async_fifo_reset_faster_write_clk (self ):
522+ fifo = AsyncFIFO (width = 32 , depth = 2 , r_domain = "read" , w_domain = "write" )
523+ self .check_async_fifo_reset (fifo , r_period = 50e-9 , w_period = 10e-9 )
524+
525+ def test_async_fifo_reset_faster_read_clk (self ):
526+ fifo = AsyncFIFO (width = 32 , depth = 2 , r_domain = "read" , w_domain = "write" )
527+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 50e-9 )
528+
529+ def test_async_buffered_fifo_reset_same_clk (self ):
530+ fifo = AsyncFIFOBuffered (width = 32 , depth = 3 , r_domain = "read" , w_domain = "write" )
531+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 10e-9 )
532+
533+ def test_async_buffered_fifo_reset_phase_180deg (self ):
534+ fifo = AsyncFIFOBuffered (width = 32 , depth = 3 , r_domain = "read" , w_domain = "write" )
535+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 10e-9 , r_phase = 0.0 , w_phase = 5e-9 )
536+
537+ def test_async_buffered_fifo_reset_faster_write_clk (self ):
538+ fifo = AsyncFIFOBuffered (width = 32 , depth = 3 , r_domain = "read" , w_domain = "write" )
539+ self .check_async_fifo_reset (fifo , r_period = 50e-9 , w_period = 10e-9 )
540+
541+ def test_async_buffered_fifo_reset_faster_read_clk (self ):
542+ fifo = AsyncFIFOBuffered (width = 32 , depth = 3 , r_domain = "read" , w_domain = "write" )
543+ self .check_async_fifo_reset (fifo , r_period = 10e-9 , w_period = 50e-9 )
0 commit comments