diff options
| author | Private Island Networks Inc <opensource@privateisland.tech> | 2025-12-21 20:51:04 -0500 |
|---|---|---|
| committer | Private Island Networks Inc <opensource@privateisland.tech> | 2025-12-21 20:51:04 -0500 |
| commit | 7b1b5e7eb712d41888398934834cae730e0aa5a0 (patch) | |
| tree | 8b8aba85e19a079fbbd4962c57ff89ca701c6e4d /src/drop_fifo.v | |
| parent | f4bdc9f4365d3a3ce3f906e68cd018cb57561e56 (diff) | |
betsy: preliminary beta snapshot
Diffstat (limited to 'src/drop_fifo.v')
| -rw-r--r-- | src/drop_fifo.v | 328 |
1 files changed, 187 insertions, 141 deletions
diff --git a/src/drop_fifo.v b/src/drop_fifo.v index 736947c..faefac0 100644 --- a/src/drop_fifo.v +++ b/src/drop_fifo.v @@ -1,8 +1,8 @@ /* * drop_fifo.v * - * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. - * Copyright 2023 Private Island Networks Inc. + * Copyright (C) 2023-2025 Private Island Networks Inc. + * Copyright (C) 2018-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. @@ -23,154 +23,200 @@ */ 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 + input rstn, + input phy_up, // Use the associated PHY state to gate write activity into the DF + input rx_clk, + input tx_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_idle, // Use to clean up states and pointers + input rx_error, + + // output data + output reg we_out, // assert when data is available for writing to the next stage + 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; + // local parameters and includes + localparam SZ_DPRAM = 16'd2048; -/* - * 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; + // 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 wr_done_m1, wr_done_m2, wr_done_m3; // CDC flag + reg rx_idle_m1, rx_idle_m2; + reg kept; + wire fifo_empty; + reg [15:0] df_bytes; + + /* + * kept: assert for length of write duration after keep asserts (when enable is active) + */ + always @(posedge rx_clk, negedge rstn) + if(!rstn) + kept <= 1'b0; + else if (read_run_m2) // CDC flag that is asserted for multiple clocks + kept <= 1'b0; + else if (phy_up && keep && enable) + kept <= 1'b1; + + /* + * wr_ptr0 logic + */ + always @(posedge rx_clk, negedge rstn) + if(!rstn) + wr_ptr0 <= 'd0; + else if (phy_up && we_in) + wr_ptr0 <= wr_ptr0 + 1'b1; + + + // convert clock domain for rx_idle + always @(posedge tx_clk, negedge rstn) + if(!rstn) begin + rx_idle_m1 <= 1'b0; + rx_idle_m2 <= 1'b0; + end + else begin + rx_idle_m1 <= rx_idle; + rx_idle_m2 <= rx_idle_m1; + end + + // convert clock domain for wr_done + always @(posedge tx_clk, negedge rstn) + if(!rstn) begin + wr_done_m1 <= 1'b0; + wr_done_m2 <= 1'b0; + wr_done_m3 <= 1'b0; + end + else begin + wr_done_m1 <= wr_done; + wr_done_m2 <= wr_done_m1; + wr_done_m3 <= wr_done_m2; + end + + /* + * wr_ptr1 logic + * sync pointers at end of RX packet + */ + always @(posedge tx_clk, negedge rstn) + if(!rstn) + wr_ptr1 <= 'd0; + else if (phy_up && wr_done_m3) + wr_ptr1 <= wr_ptr0; // + else if (rx_idle_m2 && !read_run) + wr_ptr1 <= wr_ptr0; // final clean up + + /* + * read_run logic + * continues until the FIFO is empty + */ + always @(posedge tx_clk, negedge rstn) + if(!rstn) + read_run <= 1'b0; + else if (phy_up && kept && wr_done_m3) + read_run <= 1'b1; + else if (fifo_empty) + read_run <= 1'b0; -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; + always @(posedge tx_clk, negedge rstn) + if(!rstn) begin + read_run_m1 <= 1'b0; + read_run_m2 <= 1'b0; + end + else begin + read_run_m1 <= read_run; + read_run_m2 <= read_run_m1; + end -/* - * 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); + /* + * rd_ptr logic + */ + always @(posedge tx_clk, negedge rstn) + if(!rstn) + rd_ptr <= 'd0; + else if (phy_up && kept && wr_done_m2) + 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; -/* - * d_out register - * - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - d_out <= 'd0; - else - d_out <= d_out_internal; + /* + * we_out logic + */ + always @(posedge tx_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; -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 ) -); - + assign fifo_empty = (wr_ptr1 == rd_ptr); + + /* + * d_out register + * + */ + always @(posedge tx_clk, negedge rstn) + if(!rstn) + d_out <= 'd0; + else + d_out <= d_out_internal; + + // debug flag + always @(posedge tx_clk, negedge rstn) + if(!rstn) + active <= 1'b0; + else if (we_in || we_out) + active <= 1'b1; + else + active <= 1'b0; + + /* + * debug: bytes in DF + */ + always @(posedge rx_clk, negedge rstn) + if(!rstn) + df_bytes <= 'd0; + else if (! phy_up) + df_bytes <= 'd0; + else + if (wr_ptr1 <= wr_ptr0) + df_bytes <= (wr_ptr0 + 1'b1) - wr_ptr1; + else + df_bytes <= SZ_DPRAM + (wr_ptr0+1'b1) - wr_ptr1; + + + dpram_inf dpram_fifo( + .rstn(rstn), + .a_clk(rx_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(tx_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 |



