diff options
| author | Private Island Networks <opensource@privateisland.tech> | 2025-09-01 12:34:17 -0400 |
|---|---|---|
| committer | Private Island Networks <opensource@privateisland.tech> | 2025-09-01 12:34:17 -0400 |
| commit | c8b273c80abe98e53828f46079a187975938a56a (patch) | |
| tree | 410577af8067ee001ba473dcf0c7bcae46d83de1 /src/drop_fifo.v | |
| parent | ac2bbbd2f816c223ef4dcfa2f8440d9c0c73bffe (diff) | |
rename source to src
Diffstat (limited to 'src/drop_fifo.v')
| -rw-r--r-- | src/drop_fifo.v | 176 |
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 |



