diff --git a/flow.sh b/flow.sh index 8a441ca..def150a 100755 --- a/flow.sh +++ b/flow.sh @@ -72,6 +72,7 @@ run_sims() { printinfo "Start simulation" cd "$FIFO_DIR"/sim svutRun -f files.f -test async_fifo_unit_test.sv -sim icarus + svutRun -f files.f -test async_fifo_almost_threshold_test.sv -sim icarus return $? } diff --git a/rtl/rptr_empty.v b/rtl/rptr_empty.v index c95f125..6263537 100644 --- a/rtl/rptr_empty.v +++ b/rtl/rptr_empty.v @@ -21,7 +21,7 @@ module rptr_empty ); reg [ADDRSIZE:0] rbin; - wire [ADDRSIZE:0] rgraynext, rbinnext, rgraynextm1; + wire [ADDRSIZE:0] rgraynext, rbinnext, rgraynextm1,rbinnextm1; wire arempty_val, rempty_val; //------------------- @@ -39,8 +39,9 @@ module rptr_empty // Memory read-address pointer (okay to use binary to address memory) assign raddr = rbin[ADDRSIZE-1:0]; assign rbinnext = rbin + (rinc & ~rempty); + assign rbinnextm1 = rbin + (rinc & ~rempty) + AREMPTYSIZE; assign rgraynext = (rbinnext >> 1) ^ rbinnext; - assign rgraynextm1 = ((rbinnext + AREMPTYSIZE) >> 1) ^ (rbinnext + AREMPTYSIZE); + assign rgraynextm1 = (rbinnextm1 >> 1) ^ rbinnextm1;; //--------------------------------------------------------------- // FIFO empty when the next rptr == synchronized wptr or on reset diff --git a/rtl/wptr_full.v b/rtl/wptr_full.v index 11158a0..a36b91e 100644 --- a/rtl/wptr_full.v +++ b/rtl/wptr_full.v @@ -21,7 +21,7 @@ module wptr_full ); reg [ADDRSIZE:0] wbin; - wire [ADDRSIZE:0] wgraynext, wbinnext, wgraynextp1; + wire [ADDRSIZE:0] wgraynext, wbinnext, wgraynextp1,wbinnextp1; wire awfull_val, wfull_val; // GRAYSTYLE2 pointer @@ -37,8 +37,9 @@ module wptr_full // Memory write-address pointer (okay to use binary to address memory) assign waddr = wbin[ADDRSIZE-1:0]; assign wbinnext = wbin + (winc & ~wfull); + assign wbinnextp1 = wbin + (winc & ~wfull) + AWFULLSIZE; assign wgraynext = (wbinnext >> 1) ^ wbinnext; - assign wgraynextp1 = ((wbinnext + AWFULLSIZE) >> 1) ^ (wbinnext + AWFULLSIZE); + assign wgraynextp1 = (wbinnextp1 >> 1) ^ wbinnextp1; //------------------------------------------------------------------ // Simplified version of the three necessary full-tests: diff --git a/sim/async_fifo_almost_threshold_test.sv b/sim/async_fifo_almost_threshold_test.sv new file mode 100644 index 0000000..46c5052 --- /dev/null +++ b/sim/async_fifo_almost_threshold_test.sv @@ -0,0 +1,156 @@ + +`include "svut_h.sv" +`timescale 1 ns / 1 ps + +module async_fifo_unit_test; + + `SVUT_SETUP + + `ifndef AEMPTY + `define AEMPTY 1 + `endif + + `ifndef AFULL + `define AFULL 1 + `endif + + `ifndef FALLTHROUGH + `define FALLTHROUGH "TRUE" + `endif + + parameter DSIZE = 16; + parameter ASIZE = 13; + parameter AREMPTYSIZE = `AEMPTY; + parameter AWFULLSIZE = 4096; + parameter FALLTHROUGH = `FALLTHROUGH; + parameter MAX_TRAFFIC = 10; + + integer timeout; + + reg wclk; + reg wrst_n; + reg winc; + reg [DSIZE-1:0] wdata; + wire wfull; + wire awfull; + reg rclk; + reg rrst_n; + reg rinc; + wire [DSIZE-1:0] rdata; + wire rempty; + wire arempty; + + async_fifo + #( + .DSIZE (DSIZE), + .ASIZE (ASIZE), + .AWFULLSIZE (AWFULLSIZE), + .AREMPTYSIZE (AREMPTYSIZE), + .FALLTHROUGH (FALLTHROUGH) + ) + dut + ( + wclk, + wrst_n, + winc, + wdata, + wfull, + awfull, + rclk, + rrst_n, + rinc, + rdata, + rempty, + arempty + ); + + // An example to create a clock + initial wclk = 1'b0; + always #2 wclk <= ~wclk; + initial rclk = 1'b0; + always #3 rclk <= ~rclk; + + // An example to dump data for visualization + initial begin + $dumpfile("async_fifo_unit_test.vcd"); + $dumpvars(0, async_fifo_unit_test); + end + + task setup(msg="Setup testcase"); + begin + + wrst_n = 1'b0; + winc = 1'b0; + wdata = 0; + rrst_n = 1'b0; + rinc = 1'b0; + #100; + wrst_n = 1; + rrst_n = 1; + #50; + timeout = 0; + @(posedge wclk); + + end + endtask + + task teardown(msg="Tearing down"); + begin + #50; + end + endtask + + `TEST_SUITE("ASYNCFIFO") + + `UNIT_TEST("TEST_IDLE") + + `FAIL_IF(wfull); + `FAIL_IF(!rempty); + + `UNIT_TEST_END + + + `UNIT_TEST("TEST_MULTIPLE_WRITE_THEN_READ") + + + // repeat for 3 times + + for( int j = 0; j < 3; j= j+1)begin + + // write 4096 data + winc = 1; + for (int i=0; i<(2**(ASIZE-1)); i=i+1) begin + + @(negedge wclk) + wdata = i; + + end + + @(negedge wclk); + winc = 0; + + @(posedge wclk) + `FAIL_IF_NOT_EQUAL(awfull, 1); + + + // try to read it + @(posedge rclk); + + rinc = 1; + for (int i=0; i<(2**(ASIZE-1)); i=i+1) begin + @(posedge rclk); + `FAIL_IF_NOT_EQUAL(rdata, i); + end + @(negedge rclk); + rinc = 0; + + `FAIL_IF(rempty == 0); + + end + + + `UNIT_TEST_END + + `TEST_SUITE_END + +endmodule \ No newline at end of file