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/half_fifo.v | |
| parent | f4bdc9f4365d3a3ce3f906e68cd018cb57561e56 (diff) | |
betsy: preliminary beta snapshot
Diffstat (limited to 'src/half_fifo.v')
| -rw-r--r-- | src/half_fifo.v | 299 |
1 files changed, 149 insertions, 150 deletions
diff --git a/src/half_fifo.v b/src/half_fifo.v index c85f6ac..fb02176 100644 --- a/src/half_fifo.v +++ b/src/half_fifo.v @@ -50,170 +50,169 @@ module half_fifo #(parameter DATA_WIDTH = 9, DPRAM_DEPTH=11) output reg [10:0] tx_byte_cnt, output [DATA_WIDTH-1:0] fifo_d_out, output tx_empty - ); `define INCLUDED `include "cont_params.v" `undef INCLUDED -/* - * Pointers for accessing memory. - * UC writes TX and reads RX - * Switch writes (via FIFO I/F) RX and reads TX - * This is the opposite of the system view - */ -reg [DPRAM_DEPTH-1:0] rx_wr_ptr, rx_wr_ptr_latched; - -reg [DPRAM_DEPTH-1:0] tx_wr_ptr, tx_wr_ptr_latched; -reg [DPRAM_DEPTH-1:0] tx_rd_ptr; - -reg tx_wr_ptr_written, tx_wr_ptr_written_m1, tx_wr_ptr_written_m2; - -reg fifo_we_m1; - -reg reset_ptrs; -wire [DATA_WIDTH-1:0] dpram_tx_dout, dpram_rx_dout; - -/* read data mux, refer to addr params above */ -always @(*) - casez({ dpram_tx_sel, dpram_rx_sel, dpram_ptrs_sel, dpram_addr[2:0] }) - 6'b001000: dpram_dout = tx_wr_ptr; - 6'b001001: dpram_dout = tx_rd_ptr; // meta stable - 6'b001010: dpram_dout = rx_wr_ptr_latched; - 6'b001011: dpram_dout = 11'd0; - 6'b001100: dpram_dout = {10'd0, reset_ptrs}; - 6'b010???: dpram_dout = {2'b00, dpram_rx_dout}; - 6'b100???: dpram_dout = {2'b00, dpram_tx_dout}; - default: dpram_dout = {2'b00, dpram_rx_dout}; - endcase + /* + * Pointers for accessing memory. + * UC writes TX and reads RX + * Switch writes (via FIFO I/F) RX and reads TX + * This is the opposite of the system view + */ + reg [DPRAM_DEPTH-1:0] rx_wr_ptr, rx_wr_ptr_latched; -always @(posedge uc_clk, negedge rstn) - if (!rstn) - reset_ptrs <= 1'b0; - else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_RESET_PTRS) - reset_ptrs <= dpram_din[0]; + reg [DPRAM_DEPTH-1:0] tx_wr_ptr, tx_wr_ptr_latched; + reg [DPRAM_DEPTH-1:0] tx_rd_ptr; -always @(posedge uc_clk, negedge rstn) - if (!rstn) - tx_byte_cnt <= 11'd0; - else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_TX_BYTE_CNT_ADDR) - tx_byte_cnt <= dpram_din; - -/* TX wr ptr (UC writes) */ -always @(posedge uc_clk, negedge rstn) - if (!rstn) begin - tx_wr_ptr <= 'h0; - tx_wr_ptr_written <= 1'b0; - end - else if (reset_ptrs) begin - tx_wr_ptr <= 'h0; - tx_wr_ptr_written <= 1'b1; - end - else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_TX_WR_PTR_ADDR) begin - tx_wr_ptr <= dpram_din; - tx_wr_ptr_written <= 1'b1; - end - else - tx_wr_ptr_written <= 1'b0; + reg tx_wr_ptr_written, tx_wr_ptr_written_m1, tx_wr_ptr_written_m2; -always @(posedge fifo_clk, negedge rstn) - if (!rstn) begin - tx_wr_ptr_written_m1 <= 1'b0; - tx_wr_ptr_written_m2 <= 1'b0; - end - else begin - tx_wr_ptr_written_m1 <= tx_wr_ptr_written; - tx_wr_ptr_written_m2 <= tx_wr_ptr_written_m1; - end + reg fifo_we_m1; + reg reset_ptrs; + wire [DATA_WIDTH-1:0] dpram_tx_dout, dpram_rx_dout; -always @(posedge fifo_clk, negedge rstn) - if(!rstn) - tx_wr_ptr_latched <= 8'h00; - else if (tx_wr_ptr_written_m2) - tx_wr_ptr_latched <= tx_wr_ptr; + /* read data mux, refer to addr params above */ + always @(*) + casez({ dpram_tx_sel, dpram_rx_sel, dpram_ptrs_sel, dpram_addr[2:0] }) + 6'b001000: dpram_dout = tx_wr_ptr; + 6'b001001: dpram_dout = tx_rd_ptr; // meta stable + 6'b001010: dpram_dout = rx_wr_ptr_latched; + 6'b001011: dpram_dout = 11'd0; + 6'b001100: dpram_dout = {10'd0, reset_ptrs}; + 6'b010???: dpram_dout = {2'b00, dpram_rx_dout}; + 6'b100???: dpram_dout = {2'b00, dpram_tx_dout}; + default: dpram_dout = {2'b00, dpram_rx_dout}; + endcase + + always @(posedge uc_clk, negedge rstn) + if (!rstn) + reset_ptrs <= 1'b0; + else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_RESET_PTRS) + reset_ptrs <= dpram_din[0]; + + always @(posedge uc_clk, negedge rstn) + if (!rstn) + tx_byte_cnt <= 11'd0; + else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_TX_BYTE_CNT_ADDR) + tx_byte_cnt <= dpram_din; -/* TX rd ptr (switch reads via FIFO), auto increment */ -always @(posedge fifo_clk, negedge rstn) - if(!rstn) - tx_rd_ptr <= 11'd0; - else if (reset_ptrs) - tx_rd_ptr <= 11'd0; - else if (fifo_re && !tx_empty) // advance the pointer if FIFO isn't empty - tx_rd_ptr <= tx_rd_ptr + 1'b1; - -/* RX wr ptr (switch writes via FIFO) */ -always @(posedge fifo_clk, negedge rstn) - if(!rstn) - rx_wr_ptr <= 11'd0; - else if (reset_ptrs) - rx_wr_ptr <= 11'd0; - else if (fifo_we) - rx_wr_ptr <= rx_wr_ptr + 1'b1; + /* TX wr ptr (UC writes) */ + always @(posedge uc_clk, negedge rstn) + if (!rstn) begin + tx_wr_ptr <= 'h0; + tx_wr_ptr_written <= 1'b0; + end + else if (reset_ptrs) begin + tx_wr_ptr <= 'h0; + tx_wr_ptr_written <= 1'b1; + end + else if (dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == HF_TX_WR_PTR_ADDR) begin + tx_wr_ptr <= dpram_din; + tx_wr_ptr_written <= 1'b1; + end + else + tx_wr_ptr_written <= 1'b0; + + always @(posedge fifo_clk, negedge rstn) + if (!rstn) begin + tx_wr_ptr_written_m1 <= 1'b0; + tx_wr_ptr_written_m2 <= 1'b0; + end + else begin + tx_wr_ptr_written_m1 <= tx_wr_ptr_written; + tx_wr_ptr_written_m2 <= tx_wr_ptr_written_m1; + end + + + always @(posedge fifo_clk, negedge rstn) + if(!rstn) + tx_wr_ptr_latched <= 8'h00; + else if (tx_wr_ptr_written_m2) + tx_wr_ptr_latched <= tx_wr_ptr; + + /* TX rd ptr (switch reads via FIFO), auto increment */ + always @(posedge fifo_clk, negedge rstn) + if(!rstn) + tx_rd_ptr <= 11'd0; + else if (reset_ptrs) + tx_rd_ptr <= 11'd0; + else if (fifo_re && !tx_empty) // advance the pointer if FIFO isn't empty + tx_rd_ptr <= tx_rd_ptr + 1'b1; -assign tx_empty = (tx_rd_ptr == tx_wr_ptr_latched); - -/* Assert interrupt whenever fifo_we is negated (writing is done) */ -always @(posedge fifo_clk, negedge rstn) - if (!rstn) - fifo_we_m1 <= 1'b0; - else - fifo_we_m1 <= fifo_we; + /* RX wr ptr (switch writes via FIFO) */ + always @(posedge fifo_clk, negedge rstn) + if(!rstn) + rx_wr_ptr <= 11'd0; + else if (reset_ptrs) + rx_wr_ptr <= 11'd0; + else if (fifo_we) + rx_wr_ptr <= rx_wr_ptr + 1'b1; + + assign tx_empty = (tx_rd_ptr == tx_wr_ptr_latched); -// Metastability note: rx_wr_ptr_latched should be read one or more clock cycles after rx_fifo_int asserts -always @(posedge fifo_clk, negedge rstn) - if (!rstn) begin - rx_fifo_int <= 1'b0; - rx_wr_ptr_latched <= 11'd0; - end - else if (!fifo_we & fifo_we_m1) begin // end of write - rx_fifo_int <= 1'b1; - rx_wr_ptr_latched <= rx_wr_ptr; - end - else if (rx_fifo_int_acked) // clear interrupt - rx_fifo_int <= 1'b0; + /* Assert interrupt whenever fifo_we is negated (writing is done) */ + always @(posedge fifo_clk, negedge rstn) + if (!rstn) + fifo_we_m1 <= 1'b0; + else + fifo_we_m1 <= fifo_we; + + // Metastability note: rx_wr_ptr_latched should be read one or more clock cycles after rx_fifo_int asserts + always @(posedge fifo_clk, negedge rstn) + if (!rstn) begin + rx_fifo_int <= 1'b0; + rx_wr_ptr_latched <= 11'd0; + end + else if (!fifo_we & fifo_we_m1) begin // end of write + rx_fifo_int <= 1'b1; + rx_wr_ptr_latched <= rx_wr_ptr; + end + else if (rx_fifo_int_acked) // clear interrupt + rx_fifo_int <= 1'b0; + + /* controller uses A side, FIFO uses B side + * controller writes TX path and reads RX path */ + // 2K DPRAM + dpram_inf dpram_tx( + .rstn(rstn), + .a_clk(uc_clk), + .a_clk_e(dpram_tx_sel), + .a_we(dpram_we), + .a_oe(1'b1), + .a_addr(dpram_addr), + .a_din(dpram_din[8:0]), + .a_dout(dpram_tx_dout), + // port B + .b_clk(fifo_clk), + .b_clk_e(1'b1), + .b_we(1'b0), + .b_oe(fifo_re), + .b_addr(tx_rd_ptr), + .b_din(9'h0), + .b_dout(fifo_d_out) + ); -/* controller uses A side, FIFO uses B side - * controller writes TX path and reads RX path */ -// 2K DPRAM -dpram_inf dpram_tx( - .rstn(rstn), - .a_clk(uc_clk), - .a_clk_e(dpram_tx_sel), - .a_we(dpram_we), - .a_oe(1'b1), - .a_addr(dpram_addr), - .a_din(dpram_din[8:0]), - .a_dout(dpram_tx_dout), - // port B - .b_clk(fifo_clk), - .b_clk_e(1'b1), - .b_we(1'b0), - .b_oe(fifo_re), - .b_addr(tx_rd_ptr), - .b_din(9'h0), - .b_dout(fifo_d_out) -); - -// 2K DPRAM -dpram_inf dpram_rx( - .rstn(rstn), - .a_clk(uc_clk), - .a_clk_e(dpram_rx_sel), - .a_we(1'b0), - .a_oe(1'b1), - .a_addr(dpram_addr), - .a_din(9'h000), - .a_dout(dpram_rx_dout), - // port B - .b_clk(fifo_clk), - .b_clk_e(1'b1), - .b_we(fifo_we), - .b_oe(1'b0), - .b_addr(rx_wr_ptr), - .b_din(fifo_d_in), - .b_dout() -); + // 2K DPRAM + dpram_inf dpram_rx( + .rstn(rstn), + .a_clk(uc_clk), + .a_clk_e(dpram_rx_sel), + .a_we(1'b0), + .a_oe(1'b1), + .a_addr(dpram_addr), + .a_din(9'h000), + .a_dout(dpram_rx_dout), + // port B + .b_clk(fifo_clk), + .b_clk_e(1'b1), + .b_we(fifo_we), + .b_oe(1'b0), + .b_addr(rx_wr_ptr), + .b_din(fifo_d_in), + .b_dout() + ); endmodule |



