SummerCart64/fw/rtl/sd/sd_dma.v

63 lines
1.7 KiB
Verilog

module sd_dma (
input i_clk,
input i_reset,
input i_fifo_flush,
input i_fifo_push,
output o_fifo_full,
output o_fifo_empty,
input [31:0] i_fifo_data,
output reg o_request,
output reg o_write,
input i_busy,
output reg [31:0] o_data
);
reg [31:0] r_dma_fifo_mem [0:127];
reg [6:0] r_dma_fifo_wrptr;
reg [6:0] r_dma_fifo_rdptr;
assign o_fifo_full = (r_dma_fifo_wrptr + 1'd1) == r_dma_fifo_rdptr;
assign o_fifo_empty = r_dma_fifo_wrptr == r_dma_fifo_rdptr;
wire [31:0] w_rddata = r_dma_fifo_mem[r_dma_fifo_rdptr];
wire w_request_successful = o_request && !i_busy;
always @(posedge i_clk) begin
if (i_reset || i_fifo_flush) begin
r_dma_fifo_wrptr <= 7'd0;
end else begin
if (i_fifo_push) begin
r_dma_fifo_wrptr <= r_dma_fifo_wrptr + 1'd1;
r_dma_fifo_mem[r_dma_fifo_wrptr] <= i_fifo_data;
end
end
end
always @(posedge i_clk) begin
if (i_reset || i_fifo_flush) begin
o_request <= 1'b0;
o_write <= 1'b1;
r_dma_fifo_rdptr <= 7'd0;
end else begin
if (!o_request && !o_fifo_empty) begin
o_request <= 1'b1;
o_data <= w_rddata;
r_dma_fifo_rdptr <= r_dma_fifo_rdptr + 1'd1;
end
if (w_request_successful) begin
if (o_fifo_empty) begin
o_request <= 1'b0;
end else begin
r_dma_fifo_rdptr <= r_dma_fifo_rdptr + 1'd1;
o_data <= w_rddata;
end
end
end
end
endmodule