summaryrefslogtreecommitdiffhomepage
path: root/src/half_fifo.v
diff options
context:
space:
mode:
authorPrivate Island Networks Inc <opensource@privateisland.tech>2025-12-21 20:51:04 -0500
committerPrivate Island Networks Inc <opensource@privateisland.tech>2025-12-21 20:51:04 -0500
commit7b1b5e7eb712d41888398934834cae730e0aa5a0 (patch)
tree8b8aba85e19a079fbbd4962c57ff89ca701c6e4d /src/half_fifo.v
parentf4bdc9f4365d3a3ce3f906e68cd018cb57561e56 (diff)
betsy: preliminary beta snapshot
Diffstat (limited to 'src/half_fifo.v')
-rw-r--r--src/half_fifo.v299
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

Highly Recommended Verilog Books