diff options
author | Private Island Networks Inc <opensource@privateisland.tech> | 2023-12-27 23:15:21 -0500 |
---|---|---|
committer | Private Island Networks Inc <opensource@privateisland.tech> | 2023-12-27 23:15:21 -0500 |
commit | d156dbdd24330eb0141891be188655a7cd72a3e3 (patch) | |
tree | 0079ea46a10df27fece75bef875192c092f5ade8 /source | |
parent | 55bb92f3d547aafb15926639a11b4038097eedf0 (diff) |
Diffstat (limited to 'source')
-rw-r--r-- | source/drop_fifo.v | 73 |
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 |