summaryrefslogtreecommitdiffhomepage
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/drop_fifo.v73
1 files changed, 38 insertions, 35 deletions
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

Highly Recommended Verilog Books