remove file

This commit is contained in:
2026-06-19 07:53:04 -05:00
parent dd811684dc
commit 8e7a8bbc7d

View File

@@ -1,489 +0,0 @@
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////
//
// Author : Torry Akins
// Creation Date : 06/04/2024
// File Name : dma_engine_256.sv
// Tool Version : 2021.2
// Description : DMA Engine (256 bits wide)
//
// Copyright (c) 2024 Wide Swath Research, LLC.
// This design is confidential and is the proprietary property
// of Wide Swath Research, LLC.
//
// Design licensed for use by Aloft Sensing, Inc.
//
//////////////////////////////////////////////////////////////////////////////
module dma_engine_256 (
axi4l_intf.slave axi,
axi4s_intf.slave axis,
axi4_intf.master axim
);
// incoming pipeline of write address
reg awaddr_valid;
reg [axi.AXI_ADDR_WIDTH-1:0] awaddr;
// incoming pipeline of write data
reg wdata_valid;
reg [((axi.AXI_DATA_WIDTH/8)-1):0] wstrb;
reg [axi.AXI_DATA_WIDTH-1:0] wdata;
// incoming pipeline of read address
reg araddr_valid;
reg [axi.AXI_ADDR_WIDTH:0] araddr;
// outgoing pipeline of read data
reg rvalid;
reg [axi.AXI_DATA_WIDTH-1:0] rdata;
integer byte_index;
reg [axi.AXI_DATA_WIDTH-1:0] ctrl_reg[3:0];
wire [axi.AXI_DATA_WIDTH-1:0] status_reg[4:0];
reg ctrl_fifo_wren;
reg [127:0] ctrl_fifo_din;
wire dma_rst;
wire dma_enable;
wire ctrl_fifo_rst;
reg ctrl_fifo_rden;
wire [71:0] ctrl_fifo_dout;
wire ctrl_fifo_full;
wire ctrl_fifo_empty;
wire [9:0] ctrl_fifo_count;
wire stat_fifo_rst;
reg stat_fifo_wren;
reg [71:0] stat_fifo_din;
reg stat_fifo_rden;
wire [71:0] stat_fifo_dout;
wire stat_fifo_full;
wire stat_fifo_empty;
wire [9:0] stat_fifo_count;
reg [1:0] state;
reg [71:0] active_buf;
reg [22:0] remaining_len;
reg [22:0] bytes_written;
wire s_axis_s2mm_cmd_tvalid;
wire s_axis_s2mm_cmd_tready;
reg [79:0] s_axis_s2mm_cmd_tdata;
wire m_axis_s2mm_sts_tvalid;
wire m_axis_s2mm_sts_tready;
wire [7:0] m_axis_s2mm_sts_tdata;
// ready while data hasn't been latched and still waiting
// for acknowledgement to our response
assign axi.awready = !awaddr_valid && !axi.bvalid && axi.resetn;
assign axi.wready = !wdata_valid && !axi.bvalid && axi.resetn;
always @( posedge axi.clk )
begin
if ( axi.resetn == 1'b0 ) begin
awaddr_valid <= 1'b0;
awaddr <= 'b0;
wdata_valid <= 1'b0;
wstrb <= 'b0;
wdata <= 'b0;
axi.bvalid <= 1'b0;
axi.bresp <= 2'b0;
end
else begin
// latch awaddr and valid signal
if (axi.awready && axi.awvalid) begin
awaddr_valid <= 1'b1;
awaddr <= axi.awaddr;
end
// latch wirte data and valid signal
if (axi.wready && axi.wvalid) begin
wdata_valid <= 1'b1;
wstrb <= axi.wstrb;
wdata <= axi.wdata;
end
// clear valids when both high;
// data needs to be consumed on this same condition
if (awaddr_valid && wdata_valid && !axi.bvalid) begin
awaddr_valid <= 1'b0;
wdata_valid <= 1'b0;
axi.bvalid <= 1'b1;
axi.bresp <= 2'b0; // 'OKAY' response
end
// clear bvalid when it has been acknowledged
if (axi.bvalid && axi.bready) begin
axi.bvalid <= 1'b0;
end
end
end
// ready while data hasn't been latched and still waiting
// for acknowledgement to our response
assign axi.arready = !araddr_valid && !axi.rvalid && axi.resetn;
always @( posedge axi.clk )
begin
if ( axi.resetn == 1'b0 ) begin
araddr_valid <= 1'b0;
araddr <= 'b0;
axi.rvalid <= 1'b0;
axi.rresp <= 2'b0;
axi.rdata <= 'b0;
end
else begin
// latch araddr and valid signal
if (axi.arready && axi.arvalid) begin
araddr_valid <= 1'b1;
araddr <= axi.araddr;
end
// if address is valid and rdata has been latched;
// set axi bus rdata and valid signal
if (araddr_valid && rvalid && !axi.rvalid) begin
araddr_valid <= 1'b0;
axi.rvalid <= 1'b1;
axi.rresp <= 2'b0; // 'OKAY' response
axi.rdata <= rdata;
end
// clear rvalid when it has been acknowledged
if (axi.rvalid && axi.rready) begin
axi.rvalid <= 1'b0;
end
end
end
always @( posedge axi.clk )
begin
if ( axi.resetn == 1'b0 ) begin
ctrl_reg[0] <= 'b111;
ctrl_reg[1] <= 'b0;
ctrl_reg[2] <= 'b0;
ctrl_reg[3] <= 'b0;
ctrl_fifo_wren <= 'b0;
ctrl_fifo_din <= 'b0;
stat_fifo_rden <= 1'b0;
rvalid <= 1'b0;
rdata <= 'b0;
end
else begin
ctrl_fifo_wren <= 'b0;
// everything is valid; latch data to the correct location
if (awaddr_valid && wdata_valid) begin
for ( byte_index = 0; byte_index <= (axi.AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 ) begin
if ( wstrb[byte_index] == 1 ) begin
if ( awaddr[7:0] == 'h00 )
ctrl_reg[0][(byte_index*8) +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h04 )
ctrl_reg[1][(byte_index*8) +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h08 )
ctrl_reg[2][(byte_index*8) +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h0C )
ctrl_reg[3][(byte_index*8) +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h20 )
ctrl_fifo_din[(byte_index*8) +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h24 )
ctrl_fifo_din[(byte_index*8)+32 +: 8] <= wdata[(byte_index*8) +: 8];
if ( awaddr[7:0] == 'h28 ) begin
ctrl_fifo_din[(byte_index*8)+64 +: 8] <= wdata[(byte_index*8) +: 8];
if (byte_index == 0) ctrl_fifo_wren <= 1'b1;
end
end
end
end
stat_fifo_rden <= 1'b0;
// by default rvalid is low; unless read address is valid;
// latch appropriate data and set valid signal
rvalid <= 1'b0;
if (araddr_valid && !rvalid) begin
if ( araddr[7:0] == 'h0 )
rdata <= ctrl_reg[0];
if ( araddr[7:0] == 'h4 )
rdata <= ctrl_reg[1];
if ( araddr[7:0] == 'h8 )
rdata <= ctrl_reg[2];
if ( araddr[7:0] == 'hC )
rdata <= ctrl_reg[3];
if ( araddr[7:0] == 'h10 )
rdata <= status_reg[0];
if ( araddr[7:0] == 'h14 )
rdata <= status_reg[1];
if ( araddr[7:0] == 'h18 )
rdata <= status_reg[2];
if ( araddr[7:0] == 'h1C )
rdata <= status_reg[3];
if ( araddr[7:0] == 'h20 )
rdata <= stat_fifo_dout[31:0];
if ( araddr[7:0] == 'h24 ) begin
rdata <= stat_fifo_dout[63:32];
end
if ( araddr[7:0] == 'h28 ) begin
rdata <= {24'b0, stat_fifo_dout[71:64]};
stat_fifo_rden <= 1'b1;
end
if ( araddr[7:0] == 'h2C) begin
rdata <= status_reg[4];
end
rvalid <= 1'b1;
end
end
end
assign ctrl_fifo_rst = ctrl_reg[0][0];
assign stat_fifo_rst = ctrl_reg[0][1];
assign dma_rst = ctrl_reg[0][2];
assign dma_enable = ctrl_reg[0][8];
assign status_reg[0] = {30'h00, state};
assign status_reg[1] = {16'h00, 8'd23, 8'd9};
assign status_reg[2] = {6'b0, ctrl_fifo_count, 15'b0, ctrl_fifo_full};
assign status_reg[3] = {6'b0, stat_fifo_count, 15'b0, stat_fifo_empty};
assign status_reg[4] = 32'hBEEF_BEEF;
// State Machines
parameter DMA_IDLE = 0;
parameter DMA_START = 1;
parameter DMA_ACTIVE = 2;
parameter DMA_COMP = 3;
axi4s_intf # (
.AXI_DATA_WIDTH(axis.AXI_DATA_WIDTH)
)
axis_gated(
.clk(axis.clk)
);
always @( posedge axi.clk )
begin
ctrl_fifo_rden <= 1'b0;
stat_fifo_wren <= 1'b0;
if ( dma_rst == 1'b1 ) begin
state <= DMA_IDLE;
end
else begin
case (state)
DMA_IDLE: begin
s_axis_s2mm_cmd_tdata <= 'b0;
s_axis_s2mm_cmd_tdata[71:32] <= ctrl_fifo_dout[71:32];
s_axis_s2mm_cmd_tdata[30] <= 1'b1;
s_axis_s2mm_cmd_tdata[23] <= 1'b1;
s_axis_s2mm_cmd_tdata[22:0] <= ctrl_fifo_dout[31:9];
active_buf <= ctrl_fifo_dout;
remaining_len <= ctrl_fifo_dout[31:9];
bytes_written <= 'b0;
if ((ctrl_fifo_empty == 1'b0) && ( dma_enable == 1'b1 )) begin
ctrl_fifo_rden <= 1'b1;
state <= DMA_START;
end
end
DMA_START : begin
if (s_axis_s2mm_cmd_tready == 1'b1) begin
state <= DMA_ACTIVE;
end
end
DMA_ACTIVE : begin
if ((axis_gated.tready == 1'b1) && (axis_gated.tvalid == 1'b1)) begin
if ( dma_enable == 1'b1 ) begin
remaining_len <= remaining_len - (axis.AXI_DATA_WIDTH/8);
bytes_written <= bytes_written + (axis.AXI_DATA_WIDTH/8);
if (remaining_len == (axis.AXI_DATA_WIDTH/8)) begin
state <= DMA_COMP;
end
end
else begin
state <= DMA_COMP;
end
end
end
DMA_COMP: begin
if (m_axis_s2mm_sts_tvalid == 1'b1) begin //TODO: this is a bug
stat_fifo_wren <= 1'b1;
stat_fifo_din <= active_buf;
stat_fifo_din[31:9] <= bytes_written;
state <= DMA_IDLE;
end
end
default : begin
state <= DMA_IDLE;
end
endcase
end
end
assign s_axis_s2mm_cmd_tvalid = (state == DMA_START) ? 1'b1 : 1'b0;
assign axis_gated.tdata = axis.tdata;
assign axis_gated.tkeep = axis.tkeep;
assign axis_gated.tlast = ((remaining_len == (axis.AXI_DATA_WIDTH/8)) || ( dma_enable == 1'b0 )) ? 1'b1 : 1'b0;
assign axis_gated.tvalid = (state == DMA_ACTIVE) ? (( dma_enable == 1'b0 ) ? 1'b1 : axis.tvalid) : 1'b0;
assign axis.tready = (state == DMA_ACTIVE) ? axis_gated.tready : (( dma_enable == 1'b0 ) ? 1'b1 : 1'b0);
// This can be removed and changed back to just 1'b0;
assign m_axis_s2mm_sts_tready = (state == DMA_COMP) ? 1'b1 : 1'b0;
// basic idea behind datamover control;
// control fifo allows dma driver to allocate PS DDR buffer and load the physical address
// into the fifo; once the transfer is complete the result fifo will be loaded with completion result
// that will also contain the physical DDR buffer address
dma_ctrl_status_fifo_0 ctrl_fifo_i (
.clk( axi.clk ), // : IN STD_LOGIC;
.srst( ctrl_fifo_rst ), // : IN STD_LOGIC;
.din( ctrl_fifo_din[71:0] ), // : IN STD_LOGIC_VECTOR(71 DOWNTO 0);
.wr_en( ctrl_fifo_wren ), // : IN STD_LOGIC;
.rd_en( ctrl_fifo_rden ), // : IN STD_LOGIC;
.dout( ctrl_fifo_dout ), // : OUT STD_LOGIC_VECTOR(71 DOWNTO 0);
.full( ctrl_fifo_full ), // : OUT STD_LOGIC;
.empty( ctrl_fifo_empty ), // : OUT STD_LOGIC;
.data_count( ctrl_fifo_count ), // : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
.wr_rst_busy( ),
.rd_rst_busy( )
);
dma_ctrl_status_fifo_0 stat_fifo_i (
.clk( axi.clk ), // : IN STD_LOGIC;
.srst( stat_fifo_rst ), // : IN STD_LOGIC;
.din( stat_fifo_din ), // : IN STD_LOGIC_VECTOR(71 DOWNTO 0);
.wr_en( stat_fifo_wren ), // : IN STD_LOGIC;
.rd_en( stat_fifo_rden ), // : IN STD_LOGIC;
.dout( stat_fifo_dout ), // : OUT STD_LOGIC_VECTOR(71 DOWNTO 0);
.full( stat_fifo_full ), // : OUT STD_LOGIC;
.empty( stat_fifo_empty ), // : OUT STD_LOGIC;
.data_count( stat_fifo_count ), // : OUT STD_LOGIC_VECTOR(9 DOWNTO 0);
.wr_rst_busy( ),
.rd_rst_busy( )
);
// Do a soft shutdown of the datamover on a reset request. This should ensure the AXI bus does not get hung mid burst
// and allow the datamover to be instantiated without using store-forward. This will save blockrams, and is OK because we already
// have buffering in the receive path
logic s2mm_err;
logic s2mm_halt;
logic s2mm_halt_cmplt;
logic datamover_rst;
logic dma_rst_q;
logic dma_rst_q2;
logic dma_rst_red;
always @ (posedge axim.clk) begin
dma_rst_q <= dma_rst;
dma_rst_q2 <= dma_rst_q;
dma_rst_red <= dma_rst_q & ~dma_rst_q;
s2mm_halt <= dma_rst;
// Clear the datamover reset when the dma reset clears
if (dma_rst == 1'b0) begin
datamover_rst <= 1'b0;
// s2mm_halt <= 1'b0;
end
// else if (dma_rst_red == 1'b1) begin
// // Trigger soft shutdown when the dma reset signal goes high
// s2mm_halt <= 1;
// end
else if (s2mm_halt_cmplt == 1'b1) begin
// Wait for halt complete to trigger datamover reset
datamover_rst <= 1'b1;
end
end
axi_datamover_256_0 axi_datamover_0_i (
.m_axi_s2mm_aclk( axim.clk ), //
// .m_axi_s2mm_aresetn( ~dma_rst ), // : IN STD_LOGIC;
.m_axi_s2mm_aresetn( ~datamover_rst ), // : IN STD_LOGIC;
.s2mm_halt(s2mm_halt), // input wire s2mm_halt
.s2mm_halt_cmplt(s2mm_halt_cmplt), // output wire s2mm_halt_cmplt
.s2mm_allow_addr_req(1'b1), // input wire s2mm_allow_addr_req
.s2mm_addr_req_posted(), // output wire s2mm_addr_req_posted
.s2mm_wr_xfer_cmplt(), // output wire s2mm_wr_xfer_cmplt
.s2mm_ld_nxt_len(), // output wire s2mm_ld_nxt_len
.s2mm_wr_len(), // output wire [7 : 0] s2mm_wr_len
.s2mm_err(s2mm_err), // : OUT STD_LOGIC;
.m_axis_s2mm_cmdsts_awclk( axi.clk ), // : IN STD_LOGIC;
.m_axis_s2mm_cmdsts_aresetn( ~dma_rst ), // : IN STD_LOGIC;
.s_axis_s2mm_cmd_tvalid( s_axis_s2mm_cmd_tvalid ), // : IN STD_LOGIC;
.s_axis_s2mm_cmd_tready( s_axis_s2mm_cmd_tready ), // : OUT STD_LOGIC;
.s_axis_s2mm_cmd_tdata( s_axis_s2mm_cmd_tdata), // : IN STD_LOGIC_VECTOR(79 DOWNTO 0);
.m_axis_s2mm_sts_tvalid( m_axis_s2mm_sts_tvalid ), // : OUT STD_LOGIC;
.m_axis_s2mm_sts_tready( m_axis_s2mm_sts_tready), // : IN STD_LOGIC;
.m_axis_s2mm_sts_tdata( m_axis_s2mm_sts_tdata ), // : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
.m_axis_s2mm_sts_tkeep( ), // : OUT STD_LOGIC_VECTOR(0 DOWNTO 0);
.m_axis_s2mm_sts_tlast( ), // : OUT STD_LOGIC;
.m_axi_s2mm_awaddr( axim.awaddr ), // : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
.m_axi_s2mm_awlen( axim.awlen ), // : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
.m_axi_s2mm_awsize( axim.awsize ), // : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
.m_axi_s2mm_awburst( axim.awburst ), // : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
.m_axi_s2mm_awprot( axim.awprot ), // : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
.m_axi_s2mm_awcache( axim.awcache ), // : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
.m_axi_s2mm_awuser( ), // : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
.m_axi_s2mm_awvalid( axim.awvalid ), // : OUT STD_LOGIC;
.m_axi_s2mm_awready( axim.awready ), // : IN STD_LOGIC;
.m_axi_s2mm_wdata( axim.wdata ), // : OUT STD_LOGIC_VECTOR(255 DOWNTO 0);
.m_axi_s2mm_wstrb( axim.wstrb ), // : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
.m_axi_s2mm_wlast( axim.wlast ), // : OUT STD_LOGIC;
.m_axi_s2mm_wvalid( axim.wvalid ), // : OUT STD_LOGIC;
.m_axi_s2mm_wready( axim.wready ), // : IN STD_LOGIC;
.m_axi_s2mm_bresp( axim.bresp ), // : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
.m_axi_s2mm_bvalid( axim.bvalid ), // : IN STD_LOGIC;
.m_axi_s2mm_bready( axim.bready ), // : OUT STD_LOGIC;
.s_axis_s2mm_tdata( axis_gated.tdata ), // : IN STD_LOGIC_VECTOR(255 DOWNTO 0);
.s_axis_s2mm_tkeep( axis_gated.tkeep ), // : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
.s_axis_s2mm_tlast( axis_gated.tlast ), // : IN STD_LOGIC;
.s_axis_s2mm_tvalid( axis_gated.tvalid ), // : IN STD_LOGIC;
.s_axis_s2mm_tready( axis_gated.tready ) // : OUT STD_LOGIC
);
endmodule