2021-02-01 00:40:56 +01:00
|
|
|
module sd_dma (
|
|
|
|
input i_clk,
|
|
|
|
input i_reset,
|
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
input [3:0] i_dma_bank,
|
|
|
|
input [23:0] i_dma_address,
|
2021-02-09 23:58:02 +01:00
|
|
|
input [14:0] i_dma_length,
|
|
|
|
output reg [14:0] o_dma_left,
|
2021-02-06 19:35:50 +01:00
|
|
|
input i_dma_load_bank_address,
|
|
|
|
input i_dma_load_length,
|
|
|
|
input i_dma_direction,
|
|
|
|
input i_dma_start,
|
|
|
|
input i_dma_stop,
|
|
|
|
output reg o_dma_busy,
|
2021-02-01 00:40:56 +01:00
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
output o_rx_fifo_pop,
|
|
|
|
input i_rx_fifo_empty,
|
|
|
|
input [31:0] i_rx_fifo_data,
|
|
|
|
|
|
|
|
output reg o_tx_fifo_push,
|
|
|
|
input i_tx_fifo_full,
|
|
|
|
output [31:0] o_tx_fifo_data,
|
|
|
|
|
|
|
|
output o_request,
|
2021-02-01 00:40:56 +01:00
|
|
|
output reg o_write,
|
|
|
|
input i_busy,
|
2021-02-06 19:35:50 +01:00
|
|
|
input i_ack,
|
|
|
|
output reg [3:0] o_bank,
|
|
|
|
output reg [23:0] o_address,
|
|
|
|
input [31:0] i_data,
|
|
|
|
output [31:0] o_data
|
2021-02-01 00:40:56 +01:00
|
|
|
);
|
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
wire w_request_successful = o_request && !i_busy;
|
2021-02-01 00:40:56 +01:00
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
2021-02-06 19:35:50 +01:00
|
|
|
if (i_dma_load_length && !o_dma_busy) begin
|
2021-02-09 23:58:02 +01:00
|
|
|
o_dma_left <= i_dma_length;
|
|
|
|
end else if (w_request_successful && o_dma_left > 15'd0) begin
|
|
|
|
o_dma_left <= o_dma_left - 1'd1;
|
2021-02-01 00:40:56 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
2021-02-06 19:35:50 +01:00
|
|
|
if (i_reset) begin
|
|
|
|
o_dma_busy <= 1'b0;
|
2021-02-01 00:40:56 +01:00
|
|
|
end else begin
|
2021-02-06 19:35:50 +01:00
|
|
|
if (i_dma_start && !o_dma_busy) begin
|
|
|
|
o_dma_busy <= 1'b1;
|
2021-02-01 00:40:56 +01:00
|
|
|
end
|
2021-02-09 23:58:02 +01:00
|
|
|
if (i_dma_stop || (w_request_successful && o_dma_left == 15'd0)) begin
|
2021-02-06 19:35:50 +01:00
|
|
|
o_dma_busy <= 1'b0;
|
2021-02-01 00:40:56 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
assign o_rx_fifo_pop = o_dma_busy && o_write && w_request_successful;
|
|
|
|
|
2021-02-09 23:58:02 +01:00
|
|
|
assign o_tx_fifo_push = o_dma_busy && !o_write && i_ack;
|
2021-02-06 19:35:50 +01:00
|
|
|
assign o_tx_fifo_data = i_data;
|
|
|
|
|
2021-02-09 23:58:02 +01:00
|
|
|
reg r_pending_ack;
|
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
|
|
|
if (i_reset || i_dma_stop) begin
|
|
|
|
r_pending_ack <= 1'b0;
|
|
|
|
end else if (o_dma_busy && !o_write) begin
|
|
|
|
if (w_request_successful) begin
|
|
|
|
r_pending_ack <= 1'b1;
|
|
|
|
end else if (i_ack) begin
|
|
|
|
r_pending_ack <= 1'b0;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
assign o_request = o_dma_busy && (o_write ? (
|
|
|
|
!i_rx_fifo_empty
|
|
|
|
) : (
|
2021-02-09 23:58:02 +01:00
|
|
|
!r_pending_ack && !i_tx_fifo_full
|
2021-02-06 19:35:50 +01:00
|
|
|
));
|
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
2021-02-09 23:58:02 +01:00
|
|
|
if (i_dma_start && !o_dma_busy) begin
|
2021-02-06 19:35:50 +01:00
|
|
|
o_write <= i_dma_direction;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-09 23:58:02 +01:00
|
|
|
always @(posedge i_clk) begin
|
|
|
|
if (i_dma_load_bank_address && !o_dma_busy) begin
|
|
|
|
o_bank <= i_dma_bank;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
always @(posedge i_clk) begin
|
|
|
|
if (i_dma_load_bank_address && !o_dma_busy) begin
|
|
|
|
o_address <= i_dma_address;
|
|
|
|
end else if (w_request_successful) begin
|
|
|
|
o_address <= o_address + 1'd1;
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2021-02-06 19:35:50 +01:00
|
|
|
assign o_data = i_rx_fifo_data;
|
|
|
|
|
2021-02-01 00:40:56 +01:00
|
|
|
endmodule
|