DMA control module

This commit is contained in:
otroubi
2026-07-14 13:08:10 +03:00
parent d0f48ba513
commit c1031f6a26
3 changed files with 211 additions and 57 deletions

View File

@ -1,72 +1,117 @@
module dma_controller
#(
parameter AXI_ADDR_WIDTH = 16,
parameter LEN_WIDTH = 20,
parameter TAG_WIDTH = 8,
parameter AXIS_ID_WIDTH = 8,
parameter AXIS_DEST_WIDTH = 8,
parameter AXIS_USER_WIDTH = 1
parameter int unsigned READ_DESC_WIDTH = 128,
parameter int unsigned WRITE_DESC_WIDTH = 128,
parameter int unsigned READ_STATUS_WIDTH = 128,
parameter int unsigned WRITE_STATUS_WIDTH = 128
)
(
input dma_clk,
input rst,
input send,
input [127:0] desc_read,
input [127:0] desc_write,
input [127:0] status_read,
input [127:0] status_write,
//descriptor read
output wire [AXI_ADDR_WIDTH-1:0] s_axis_read_desc_addr,
output wire [LEN_WIDTH-1:0] s_axis_read_desc_len,
output wire [TAG_WIDTH-1:0] s_axis_read_desc_tag,
output wire [AXIS_ID_WIDTH-1:0] s_axis_read_desc_id,
output wire [AXIS_DEST_WIDTH-1:0] s_axis_read_desc_dest,
output wire [AXIS_USER_WIDTH-1:0] s_axis_read_desc_user,
output wire s_axis_read_desc_valid,
input wire s_axis_read_desc_ready,
input rst_n,
input logic send_desc_read,
input logic send_desc_write,
input logic take_status_read,
input logic take_status_write,
// descriptor write
output wire [AXI_ADDR_WIDTH-1:0] s_axis_write_desc_addr,
output wire [LEN_WIDTH-1:0] s_axis_write_desc_len,
output wire [TAG_WIDTH-1:0] s_axis_write_desc_tag,
output wire s_axis_write_desc_valid,
input wire s_axis_write_desc_ready,
input logic ready_desc_read,
input logic ready_desc_write,
// status read
input wire [TAG_WIDTH-1:0] m_axis_read_desc_status_tag,
input wire [3:0] m_axis_read_desc_status_error,
input wire m_axis_read_desc_status_valid,
output logic ready_status_read,
output logic ready_status_write,
input logic [READ_DESC_WIDTH-1:0] desc_read_cmd,
input logic [WRITE_DESC_WIDTH-1:0] desc_write_cmd,
output logic [READ_STATUS_WIDTH-1:0] status_read_cmd,
output logic [WRITE_STATUS_WIDTH-1:0] status_write_cmd,
input logic [READ_STATUS_WIDTH-1:0] status_read_cmd_in,
input logic [WRITE_STATUS_WIDTH-1:0] status_write_cmd_in,
output logic desc_read_dma_busy,
output logic desc_write_dma_busy,
output logic status_read_dma_busy,
output logic status_write_dma_busy,
output logic desc_read_dma_hs,
output logic desc_write_dma_hs,
output logic status_read_dma_hs,
output logic status_write_dma_hs,
output logic valid_desc_read,
output logic valid_desc_write,
input logic valid_status_read,
input logic valid_status_write,
output logic [READ_DESC_WIDTH-1:0] desc_read_cmd_out,
output logic [WRITE_DESC_WIDTH-1:0] desc_write_cmd_out
// status write
input wire [LEN_WIDTH-1:0] m_axis_write_desc_status_len,
input wire [TAG_WIDTH-1:0] m_axis_write_desc_status_tag,
input wire [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_id,
input wire [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_dest,
input wire [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_user,
input wire [3:0] m_axis_write_desc_status_error,
input wire m_axis_write_desc_status_valid
);
typedef enum logic [0:0] {
IDLE,
WAIT_READY
} wr_state;
shaper_axis_desc
#(
.DATA_WIDTH(READ_DESC_WIDTH)
) shaper_axis_desc_read
(
.clk(dma_clk),
.rst_n(rst_n),
.data_in(desc_read_cmd),
.send(send_desc_read),
.ready(ready_desc_read),
.busy(desc_read_dma_busy),
.handshake(desc_read_dma_hs),
.data_out(desc_read_cmd_out),
.valid(valid_desc_read)
);
wr_state state;
shaper_axis_desc
#(
.DATA_WIDTH(WRITE_DESC_WIDTH)
) shaper_axis_desc_write
(
.clk(dma_clk),
.rst_n(rst_n),
.data_in(desc_write_cmd),
.send(send_desc_write),
.ready(ready_desc_write),
.busy(desc_write_dma_busy),
.handshake(desc_write_dma_hs),
.data_out(desc_write_cmd_out),
.valid(valid_desc_write)
);
always @(posedge clk) begin
if (rst) begin
shaper_axis_status
#(
.DATA_WIDTH(READ_STATUS_WIDTH)
) shaper_axis_status_read
(
.clk(dma_clk),
.rst_n(rst_n),
.data_in(status_read_cmd_in),
.take(take_status_read),
.valid(valid_status_read),
.ready(ready_status_read),
.busy(status_read_dma_busy),
.handshake(status_read_dma_hs),
.data_out(status_read_cmd)
);
end else begin
case (state)
IDLE: begin
if (send) begin
end
WAIT_READY: begin
end
endcase
end
shaper_axis_status
#(
.DATA_WIDTH(READ_STATUS_WIDTH)
) shaper_axis_status_write
(
.clk(dma_clk),
.rst_n(rst_n),
.data_in(status_write_cmd_in),
.take(take_status_write),
.valid(valid_status_write),
.ready(ready_status_write),
.busy(status_write_dma_busy),
.handshake(status_write_dma_hs),
.data_out(status_write_cmd)
);
endmodule

View File

@ -0,0 +1,54 @@
module shaper_axis_desc #(
parameters DATA_WIDTH = 128;
) (
input clk;
input rst_n;
input logic [DATA_WIDTH-1:0] data_in;
input logic send;
input logic ready;
output logic busy;
output logic handshake;
output logic [DATA_WIDTH-1:0] data_out;
output logic valid;
);
typedef enum logic [0:0] {
IDLE,
WAIT_READY
} wr_state;
wr_state state;
always @(posedge clk) begin
if (!rst_n) begin
state <= IDLE;
busy <= 1'b0;
handshake <= 1'b0;
data_out <= 1'b0;
valid <= 1'b0;
end else begin
case (state)
IDLE: begin
handshake <= 1'b0;
if (send) begin
valid <= 1'b1;
data_out <= data_in;
busy <= 1'b1;
state <= WAIT_READY;
end
end
WAIT_READY: begin
if (ready) begin
valid <= 1'b0;
handshake <= 1'b1;
busy <= 1'b0;
state <= IDLE;
end
end
default: state <= IDLE;
endcase
end
end
endmodule

View File

@ -0,0 +1,55 @@
module shaper_axis_status #(
parameter int unsigned DATA_WIDTH = 128
)(
input logic clk,
input logic rst_n,
input logic [DATA_WIDTH-1:0] data_in,
input logic take,
input logic valid,
output logic ready,
output logic busy,
output logic handshake,
output logic [DATA_WIDTH-1:0] data_out
);
typedef enum logic [0:0] {
IDLE,
WAIT_VALID
} wr_state;
wr_state state;
always @(posedge clk) begin
if (!rst_n) begin
state <= IDLE;
ready <= 1'b0;
busy <= 1'b0;
handshake <= 1'b0;
data_out <= '0;
end else begin
case (state)
IDLE: begin
handshake <= 1'b0;
if (take) begin
ready <= 1'b1;
busy <= 1'b1;
state <= WAIT_VALID;
end
end
WAIT_VALID: begin
if (valid) begin
data_out <= data_in;
ready <= 1'b0;
handshake <= 1'b1;
busy <= 1'b0;
state <= IDLE;
end
end
endcase
end
end
endmodule