From d156dbdd24330eb0141891be188655a7cd72a3e3 Mon Sep 17 00:00:00 2001
From: Private Island Networks Inc <opensource@privateisland.tech>
Date: Wed, 27 Dec 2023 23:15:21 -0500
Subject: drop_fifo: fix up logic when packets are dropped

---
 source/drop_fifo.v | 73 ++++++++++++++++++++++++++++--------------------------
 1 file changed, 38 insertions(+), 35 deletions(-)

(limited to 'source')

diff --git a/source/drop_fifo.v b/source/drop_fifo.v
index de97d6d..736947c 100644
--- a/source/drop_fifo.v
+++ b/source/drop_fifo.v
@@ -2,6 +2,7 @@
  *   drop_fifo.v
  *
  *   Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc.
+ *   Copyright 2023 Private Island Networks Inc.
  *
  *   Licensed under the Apache License, Version 2.0 (the "License");
  *   you may not use this file except in compliance with the License.
@@ -16,26 +17,25 @@
  *   limitations under the License.
  *
  *	function: FIFO that supports dropping data if not kept
+ *	
+ *	For more information, see https://privateisland.tech/dev/pi-doc
  *       
  */
 
-`timescale 1ns /10ps
-
 module drop_fifo(
 		input	rstn,
 		input	clk,
-		input	enable, 
-		
-		// control (keep or drop by default)
-		input	keep,				// this packet won't be dropped, start transferring it (writer must be sure FIFO won't run dry during writes)
 		input	passthrough,		// don't store / delay data, write through instead
+		input	enable, 			// enable the FIFO
+		input	keep,				// this packet won't be dropped, start transferring it (writer must be sure FIFO won't run dry during writes)
 		
-		// input
+		// input data
 		input	we_in,
-		input  wr_done,
-		input [8:0]	d_in,
-		
-		// output
+		input 	[8:0] d_in,
+		input 	wr_done,			// keep should occur before wr_done is asserted. 
+		input 	rx_eop,
+
+		// output data
 		output 	reg we_out,
 		output	reg [8:0] d_out,
 		
@@ -47,27 +47,22 @@ module drop_fifo(
 
 
 // nets and registers
-reg	[10:0] 	wr_ptr0, wr_ptr1;	// wr_ptr0 is updated on each write; wr_ptr1 is updated on wr_done
+reg	[10:0] 	wr_ptr0, wr_ptr1;	// wr_ptr0 is updated on each write; wr_ptr1 is updated at end of packet
 reg	[10:0] 	rd_ptr;
-
 wire [8:0]  d_out_internal;
-
-reg read_run, read_run_m1;		// read continues while read_run is set					// read enable for dpram
-wire i_keep;
+reg read_run, read_run_m1, read_run_m2;		// read continues while read_run is set	
 reg kept;
 wire fifo_empty;
 
-assign i_keep = keep & enable;
-
 /* 
- * kept: assert for length of write duration after keep asserts
+ * kept: assert for length of write duration after keep asserts (when enable is active)
  */
 always @(posedge clk, negedge rstn)
 	if( !rstn )
 		kept <= 1'b0;
 	else if ( wr_done )
 		kept <= 1'b0;
-	else if ( i_keep )
+	else if ( keep && enable )
 		kept <= 1'b1;
 	
 /*
@@ -77,27 +72,17 @@ always @(posedge clk, negedge rstn)
 	if( !rstn )
 		wr_ptr0 <= 'd0;
 	else if ( we_in )
-		wr_ptr0 <= wr_ptr0 + 1;
-	
+		wr_ptr0 <= wr_ptr0 + 1'b1;
 	
 /*
  * wr_ptr1 logic
+ * sync pointers at end of rx packet for next packet
 */
 always @(posedge clk, negedge rstn)
 	if( !rstn )
 		wr_ptr1 <= 'd0;
 	else if ( wr_done )
-		wr_ptr1 <= wr_ptr0 +1;		// a write takes place with wr_done
-
-/*
- * rd_ptr logic
- */	
-always @(posedge clk, negedge rstn)
-	if( !rstn )
-		rd_ptr <= 'd0;
-	else if (read_run && !fifo_empty)
-		rd_ptr <= rd_ptr+ 1;
-	
+		wr_ptr1 <= wr_ptr0 +1;		// a write takes place with wr_done			
 	
 /*
  * 	read_run logic 
@@ -117,19 +102,37 @@ always @(posedge clk, negedge rstn)
 		read_run_m1 <= 1'b0;
 	else 
 		read_run_m1 <= read_run;
+	
+	
+always @(posedge clk, negedge rstn)
+	if( !rstn )
+		read_run_m2 <= 1'b0;
+	else 
+		read_run_m2 <= read_run_m1;
 
+/*
+* rd_ptr logic
+*/	
+always @(posedge clk, negedge rstn)
+	if( !rstn )
+		rd_ptr <= 'd0;
+	else if (kept && wr_done)
+		rd_ptr <= wr_ptr1;			// set rd_ptr to the beginning of where the write started   
+	else if (read_run && !fifo_empty)
+		rd_ptr <= rd_ptr+ 1'b1;
+	
 /*
  * 	we_out logic
  */
 always @(posedge clk, negedge rstn)
 	if( !rstn )
 		we_out <= 1'b0;
-	else if ( read_run && read_run_m1 )
+	else if ( read_run_m1 && read_run_m2 )
 		we_out <= 1'b1;
 	else
 		we_out <= 1'b0;
 
-assign fifo_empty = wr_ptr1 == rd_ptr ? 1'b1 : 1'b0;
+assign fifo_empty = (wr_ptr1 == rd_ptr);
 	
 /*
  * d_out register
-- 
cgit v1.2.3-8-gadcc