SummerCart64/fw/unused/usb_fifo.sv
Polprzewodnikowy 8501b875f9 trtashf
2021-08-16 00:23:10 +02:00

47 lines
1.3 KiB
Systemverilog

module usb_fifo #(
parameter FIFO_LENGTH = 1024,
parameter FIFO_WIDTH = 8
) (
if_system.sys system_if,
input flush,
output full,
input write,
input [(FIFO_WIDTH - 1):0] wdata,
output empty,
input read,
output reg [(FIFO_WIDTH - 1):0] rdata
);
localparam FIFO_ADDRESS_WIDTH = $clog2(FIFO_LENGTH);
reg [(FIFO_WIDTH - 1):0] r_fifo_mem [0:(FIFO_LENGTH - 1)];
reg [FIFO_ADDRESS_WIDTH:0] r_fifo_wrptr;
reg [FIFO_ADDRESS_WIDTH:0] r_fifo_rdptr;
wire w_full_or_empty = r_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0] == r_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0];
assign empty = r_fifo_wrptr == r_fifo_rdptr;
assign full = !empty && w_full_or_empty;
always_ff @(posedge system_if.clk) begin
rdata <= r_fifo_mem[r_fifo_rdptr[(FIFO_ADDRESS_WIDTH - 1):0]];
if (system_if.reset || flush) begin
r_fifo_wrptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
r_fifo_rdptr <= {(FIFO_ADDRESS_WIDTH + 1){1'b0}};
end else begin
if (write) begin
r_fifo_mem[r_fifo_wrptr[(FIFO_ADDRESS_WIDTH - 1):0]] <= wdata;
r_fifo_wrptr <= r_fifo_wrptr + 1'd1;
end
if (read) begin
r_fifo_rdptr <= r_fifo_rdptr + 1'd1;
end
end
end
endmodule