@@ -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