summaryrefslogtreecommitdiffhomepage
path: root/src/drop_fifo.v
diff options
context:
space:
mode:
authorPrivate Island Networks <opensource@privateisland.tech>2025-09-01 12:34:17 -0400
committerPrivate Island Networks <opensource@privateisland.tech>2025-09-01 12:34:17 -0400
commitc8b273c80abe98e53828f46079a187975938a56a (patch)
tree410577af8067ee001ba473dcf0c7bcae46d83de1 /src/drop_fifo.v
parentac2bbbd2f816c223ef4dcfa2f8440d9c0c73bffe (diff)
rename source to src
Diffstat (limited to 'src/drop_fifo.v')
-rw-r--r--src/drop_fifo.v176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/drop_fifo.v b/src/drop_fifo.v
new file mode 100644
index 0000000..736947c
--- /dev/null
+++ b/src/drop_fifo.v
@@ -0,0 +1,176 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * function: FIFO that supports dropping data if not kept
+ *
+ * For more information, see https://privateisland.tech/dev/pi-doc
+ *
+ */
+
+module drop_fifo(
+ input rstn,
+ input clk,
+ 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 data
+ input we_in,
+ 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,
+
+ // debug
+ output reg active
+);
+
+// local parameters and includes
+
+
+// nets and registers
+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_run_m2; // read continues while read_run is set
+reg kept;
+wire fifo_empty;
+
+/*
+ * 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 ( keep && enable )
+ kept <= 1'b1;
+
+/*
+ * wr_ptr0 logic
+ */
+always @(posedge clk, negedge rstn)
+ if( !rstn )
+ wr_ptr0 <= 'd0;
+ else if ( we_in )
+ 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
+
+/*
+ * read_run logic
+ * continues until the FIFO is empty
+ */
+always @(posedge clk, negedge rstn)
+ if( !rstn )
+ read_run <= 1'b0;
+ else if (kept && wr_done)
+ read_run <= 1'b1;
+ else if ( fifo_empty )
+ read_run <= 1'b0;
+
+
+always @(posedge clk, negedge rstn)
+ if( !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_m1 && read_run_m2 )
+ we_out <= 1'b1;
+ else
+ we_out <= 1'b0;
+
+assign fifo_empty = (wr_ptr1 == rd_ptr);
+
+/*
+ * d_out register
+ *
+ */
+always @(posedge clk, negedge rstn)
+ if( !rstn )
+ d_out <= 'd0;
+ else
+ d_out <= d_out_internal;
+
+
+always @(posedge clk, negedge rstn)
+ if( !rstn )
+ active <= 1'b0;
+ else if ( we_in || we_out )
+ active <= 1'b1;
+ else
+ active <= 1'b0;
+
+dpram dpram_fifo(
+.rstn( rstn ),
+.a_clk( clk ),
+.a_clk_e( 1'b1 ),
+.a_we( we_in ),
+.a_oe( 1'b0 ),
+.a_addr( wr_ptr0 ),
+.a_din( d_in ),
+.a_dout( ),
+// port B
+.b_clk( clk ),
+.b_clk_e( read_run ),
+.b_we( 1'b0 ),
+.b_oe( 1'b1 ),
+.b_addr( rd_ptr ),
+.b_din( 9'h0 ),
+.b_dout( d_out_internal )
+);
+
+
+endmodule

Highly Recommended Verilog Books