From 05366eaac0ece9c7b4312721c4d4e1dba75efc7b Mon Sep 17 00:00:00 2001 From: mindchasers Date: Tue, 2 Mar 2021 13:02:50 -0500 Subject: drop_fifo: first pass at a simplified approach --- source/drop_fifo.v | 157 +++++++++++++++++++---------------------------------- 1 file changed, 55 insertions(+), 102 deletions(-) (limited to 'source') diff --git a/source/drop_fifo.v b/source/drop_fifo.v index 393c20b..de97d6d 100644 --- a/source/drop_fifo.v +++ b/source/drop_fifo.v @@ -1,7 +1,7 @@ /* * drop_fifo.v * - * Copyright (C) 2018, 2019 Mind Chasers Inc. + * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * function: Double buffered side-by-side FIFO for delaying data until keep / drop decision is made + * function: FIFO that supports dropping data if not kept * */ @@ -27,7 +27,7 @@ module drop_fifo( input enable, // control (keep or drop by default) - input keep, // this packet won't be dropped, start transferring it + 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 @@ -36,7 +36,7 @@ module drop_fifo( input [8:0] d_in, // output - output we_out, + output reg we_out, output reg [8:0] d_out, // debug @@ -47,66 +47,18 @@ module drop_fifo( // nets and registers - -// the msbit of the ptr selects top or bottom half -reg [10:0] wr_ptr; +reg [10:0] wr_ptr0, wr_ptr1; // wr_ptr0 is updated on each write; wr_ptr1 is updated on wr_done reg [10:0] rd_ptr; wire [8:0] d_out_internal; -reg read_run, read_run_m1; // read continues while read_run is set -reg i_we_out, i_we_out_m1; // internal we_out -wire re; // read enable for dpram -reg rd_done_p1, rd_done; +reg read_run, read_run_m1; // read continues while read_run is set // read enable for dpram wire i_keep; reg kept; +wire fifo_empty; assign i_keep = keep & enable; - -/* - * read_run logic - * read starts after each keep assertion - * continues until the FIFO is empty - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - read_run <= 1'b0; - else if ( rd_done_p1 ) - read_run <= 1'b0; - else if ( i_keep ) - read_run <= 1'b1; - - -always @(posedge clk, negedge rstn) - if( !rstn ) - read_run_m1 <= 1'b0; - else - read_run_m1 <= read_run; - -assign re = read_run; - -/* - * we_out logic - * delayed version of re - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - i_we_out <= 1'b0; - else if ( read_run && read_run_m1 ) - i_we_out <= 1'b1; - else - i_we_out <= 1'b0; - -always @(posedge clk, negedge rstn) - if( !rstn ) - i_we_out_m1 <= 1'b0; - else - i_we_out_m1 <= i_we_out; - -// OR these two signals to stretch we_out to the last byte from FIFO -assign we_out = i_we_out | i_we_out_m1; - /* * kept: assert for length of write duration after keep asserts */ @@ -119,48 +71,65 @@ always @(posedge clk, negedge rstn) kept <= 1'b1; /* - * upper / lower half DPRAM logic - * directs upper or lower write buffer in FIFO - * toggle each time a packet is kept and write is finished + * wr_ptr0 logic */ always @(posedge clk, negedge rstn) - if ( !rstn ) - wr_ptr[10] <= 1'b0; // init to the lower bank - else if ( wr_done && kept ) - wr_ptr[10] <= ~wr_ptr[10]; + if( !rstn ) + wr_ptr0 <= 'd0; + else if ( we_in ) + wr_ptr0 <= wr_ptr0 + 1; + /* - * wr_ptr logic excluding msbit - * reset pointer when wr_done - */ + * wr_ptr1 logic +*/ always @(posedge clk, negedge rstn) if( !rstn ) - wr_ptr[9:0] <= 'd0; + wr_ptr1 <= 'd0; else if ( wr_done ) - wr_ptr[9:0] <= 'd0; - else if ( we_in ) - wr_ptr[9:0] <= wr_ptr[9:0] + 1; + wr_ptr1 <= wr_ptr0 +1; // a write takes place with wr_done -/* - * each time the FIFO is empty, set rd_ptr[10] to wr_ptr[10] - * FIFO becomes empty through reading - */ +/* + * rd_ptr logic + */ always @(posedge clk, negedge rstn) - if ( !rstn ) - rd_ptr[10] <= 1'b0; // init to the lower bank - else if ( rd_done ) - rd_ptr[10] <= wr_ptr[10]; + if( !rstn ) + rd_ptr <= 'd0; + else if (read_run && !fifo_empty) + rd_ptr <= rd_ptr+ 1; + /* - * rd_ptr logic excluding msbit - */ + * 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 ) - rd_ptr[9:0] <= 'd0; - else if ( rd_done ) - rd_ptr[9:0] <= 'd0; - else if ( re ) - rd_ptr[9:0] <= rd_ptr[9:0] + 1; + read_run_m1 <= 1'b0; + else + read_run_m1 <= read_run; + +/* + * we_out logic + */ +always @(posedge clk, negedge rstn) + if( !rstn ) + we_out <= 1'b0; + else if ( read_run && read_run_m1 ) + we_out <= 1'b1; + else + we_out <= 1'b0; + +assign fifo_empty = wr_ptr1 == rd_ptr ? 1'b1 : 1'b0; /* * d_out register @@ -172,22 +141,6 @@ always @(posedge clk, negedge rstn) else d_out <= d_out_internal; - -/* -* rd_done logic -*/ -always @(posedge clk, negedge rstn) - if( !rstn ) - begin - rd_done_p1 <= 1'b0; - rd_done <= 1'b0; - end - else - begin - rd_done_p1 <= d_out_internal[8]; - rd_done <= rd_done_p1; - end - always @(posedge clk, negedge rstn) if( !rstn ) @@ -203,12 +156,12 @@ dpram dpram_fifo( .a_clk_e( 1'b1 ), .a_we( we_in ), .a_oe( 1'b0 ), -.a_addr( wr_ptr ), +.a_addr( wr_ptr0 ), .a_din( d_in ), .a_dout( ), // port B .b_clk( clk ), -.b_clk_e( re ), +.b_clk_e( read_run ), .b_we( 1'b0 ), .b_oe( 1'b1 ), .b_addr( rd_ptr ), -- cgit v1.2.3-8-gadcc