Skip to content

Commit

Permalink
dmac_api/trans: Support autorun,framelock
Browse files Browse the repository at this point in the history
AUTORUN mode is meant to be executed without a processing system, so the
whole execution should occur without writing any register, only by
parametrizing, at dmac_api, skip any writes during the probe.
Add framelock methods to support the framelock feature.

Signed-off-by: Jorge Marques <[email protected]>
  • Loading branch information
gastmaier committed Nov 19, 2024
1 parent c5418a6 commit 2124530
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 78 deletions.
77 changes: 75 additions & 2 deletions library/drivers/dmac/dma_trans.sv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
// Copyright 2014 - 2018, 2024 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
Expand Down Expand Up @@ -44,10 +44,15 @@ package dma_trans_pkg;
int DMA_DATA_WIDTH_SRC;
int DMA_DATA_WIDTH_DEST;
int DMA_2D_TRANSFER;
int DMA_2D_TLAST_MODE;
int DMA_TYPE_SRC;
int DMA_TYPE_DEST;
int DMA_LENGTH_ALIGN;
int MAX_BYTES_PER_BURST;
int FRAMELOCK;
int MAX_NUM_FRAMES;
int USE_EXT_SYNC;
int HAS_AUTORUN;
} axi_dmac_params_t;

//==========================================================================
Expand Down Expand Up @@ -284,7 +289,7 @@ package dma_trans_pkg;
s.dst_addr = dst_addr + i*dst_stride;
s.length = length;
if (i != ylength-1)
s.last = 0;
s.last = (p.DMA_2D_TLAST_MODE == 1) & this.last;
if (i > 0)
s.first = 0;
sa[i] = s;
Expand Down Expand Up @@ -393,6 +398,74 @@ package dma_trans_pkg;

endclass : dma_partial_2d_segment

//==========================================================================
/*
dma_flocked_2d_segment
*/
//==========================================================================
class dma_flocked_2d_segment extends dma_2d_segment;

rand int unsigned flock_distance;
int flock_wait_writer = 1;
int flock_mode = 0; // 0 - dynamic. 1 - simple
rand int unsigned flock_framenum;
int unsigned flock_stride;

// -----------------
//
// -----------------
function new(axi_dmac_params_t p);
super.new(p);
endfunction

// -----------------
//
// -----------------
function copy(dma_flocked_2d_segment ds);
super.copy(ds);
ds.flock_framenum = flock_framenum;
ds.flock_distance = flock_distance;
ds.flock_stride = flock_stride;
ds.flock_mode = flock_mode;
ds.flock_wait_writer = flock_wait_writer;
endfunction

constraint c_buf_num {flock_framenum < p.MAX_NUM_FRAMES;};
constraint c_frm_dist {flock_distance < flock_framenum;};

virtual function void print();
super.print();
`INFO(("flock_framenum is %0d", flock_framenum));
`INFO(("flock_distance is %0d", flock_distance));
`INFO(("flock_stride is 0x%0h", flock_stride));
endfunction


// -----------------
//
// -----------------
function void post_randomize();
super.post_randomize();
flock_stride = length * ylength;
cyclic = 1;
endfunction


// -----------------
//
// -----------------
function dma_flocked_2d_segment toSlaveSeg;
dma_flocked_2d_segment seg;
seg = new(this.p);
this.copy(seg);
seg.src_addr = seg.dst_addr;
seg.src_stride = seg.dst_stride;

return seg;
endfunction

endclass : dma_flocked_2d_segment

//==========================================================================
/*
dma_transfer
Expand Down
100 changes: 67 additions & 33 deletions library/drivers/dmac/dmac_api.sv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ***************************************************************************
// ***************************************************************************
// Copyright 2014 - 2018 (c) Analog Devices, Inc. All rights reserved.
// Copyright 2014 - 2018, 2024 (c) Analog Devices, Inc. All rights reserved.
//
// In this HDL repository, there are many different and unique modules, consisting
// of various HDL (Verilog or VHDL) components. The individual modules are
Expand Down Expand Up @@ -59,34 +59,46 @@ package dmac_api_pkg;
// -----------------
//
// -----------------
// Discover HW parameters
task discover_params();
// Discover HW parameters
task discover_params();
bit [31:0] val;
bit [3:0] bpb_dest_log2, bpb_src_log2, bpb_width_log2;
this.axi_read(GetAddrs(DMAC_PERIPHERAL_ID), val);
this.axi_read(GetAddrs(DMAC_PERIPHERAL_ID), val);
p.ID = `GET_DMAC_PERIPHERAL_ID_PERIPHERAL_ID(val);
this.axi_read(GetAddrs(DMAC_INTERFACE_DESCRIPTION), val);
bpb_dest_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_BYTES_PER_BEAT_DEST_LOG2(val);
this.axi_read(GetAddrs(DMAC_INTERFACE_DESCRIPTION_1), val);
bpb_dest_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_1_BYTES_PER_BEAT_DEST_LOG2(val);
p.DMA_DATA_WIDTH_DEST = (2**bpb_dest_log2)*8;
p.DMA_TYPE_DEST = `GET_DMAC_INTERFACE_DESCRIPTION_DMA_TYPE_DEST(val);
bpb_src_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_BYTES_PER_BEAT_SRC_LOG2(val);
p.DMA_TYPE_DEST = `GET_DMAC_INTERFACE_DESCRIPTION_1_DMA_TYPE_DEST(val);
bpb_src_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_1_BYTES_PER_BEAT_SRC_LOG2(val);
p.DMA_DATA_WIDTH_SRC = (2**bpb_src_log2)*8;
p.DMA_TYPE_SRC = `GET_DMAC_INTERFACE_DESCRIPTION_DMA_TYPE_SRC(val);
bpb_width_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_BYTES_PER_BURST_WIDTH(val);
p.DMA_TYPE_SRC = `GET_DMAC_INTERFACE_DESCRIPTION_1_DMA_TYPE_SRC(val);
bpb_width_log2 = `GET_DMAC_INTERFACE_DESCRIPTION_1_BYTES_PER_BURST_WIDTH(val);
p.MAX_BYTES_PER_BURST = 2**bpb_width_log2;
this.axi_write(GetAddrs(DMAC_X_LENGTH),
`SET_DMAC_X_LENGTH_X_LENGTH(32'h0));
p.DMA_2D_TLAST_MODE = `GET_DMAC_INTERFACE_DESCRIPTION_1_DMA_2D_TLAST_MODE(val);
p.MAX_NUM_FRAMES = `GET_DMAC_INTERFACE_DESCRIPTION_1_MAX_NUM_FRAMES(val);
p.USE_EXT_SYNC = `GET_DMAC_INTERFACE_DESCRIPTION_1_USE_EXT_SYNC(val);
p.HAS_AUTORUN = `GET_DMAC_INTERFACE_DESCRIPTION_1_HAS_AUTORUN(val);
if (!p.HAS_AUTORUN) begin
this.axi_write(GetAddrs(DMAC_X_LENGTH),
`SET_DMAC_X_LENGTH_X_LENGTH(32'h0));
end
this.axi_read(GetAddrs(DMAC_X_LENGTH), val);
p.DMA_LENGTH_ALIGN = `GET_DMAC_X_LENGTH_X_LENGTH(val)+1;
this.axi_write(GetAddrs(DMAC_Y_LENGTH),
`SET_DMAC_Y_LENGTH_Y_LENGTH(32'hFFFFFFFF));
if (!p.HAS_AUTORUN) begin
this.axi_write(GetAddrs(DMAC_Y_LENGTH),
`SET_DMAC_Y_LENGTH_Y_LENGTH(32'hFFFFFFFF));
end
this.axi_read(GetAddrs(DMAC_Y_LENGTH), val);
if (val==0) begin
p.DMA_2D_TRANSFER = 0;
end else begin
end else begin
p.DMA_2D_TRANSFER = 1;
this.axi_write(GetAddrs(DMAC_Y_LENGTH), 32'h0);
if (!p.HAS_AUTORUN) begin
this.axi_write(GetAddrs(DMAC_Y_LENGTH), 32'h0);
end
end
this.axi_read(GetAddrs(DMAC_FLAGS), val);
p.FRAMELOCK = `GET_DMAC_CONTROL_FRAMELOCK(val);
endtask : discover_params

// -----------------
Expand Down Expand Up @@ -117,25 +129,36 @@ package dmac_api_pkg;
// -----------------
task enable_dma();
this.axi_write(GetAddrs(DMAC_CONTROL),
`SET_DMAC_CONTROL_ENABLE(1));
`SET_DMAC_CONTROL_ENABLE(1));
endtask : enable_dma

// -----------------
//
// -----------------
task disable_dma();
this.axi_write(GetAddrs(DMAC_CONTROL),
`SET_DMAC_CONTROL_PAUSE(0));
`SET_DMAC_CONTROL_PAUSE(0));
endtask : disable_dma

// -----------------
//
// -----------------
task set_flags(input bit[2:0] flags);
task set_control(input bit[3:0] control);
this.axi_write(GetAddrs(DMAC_CONTROL),
`SET_DMAC_CONTROL_ENABLE(control[0]) |
`SET_DMAC_CONTROL_PAUSE(control[1]) |
`SET_DMAC_CONTROL_HWDESC(control[2]) |
`SET_DMAC_CONTROL_FRAMELOCK(control[3]));
endtask : set_control

// -----------------
//
// -----------------
task set_flags(input bit[3:0] flags);
this.axi_write(GetAddrs(DMAC_FLAGS),
`SET_DMAC_FLAGS_CYCLIC(flags[0])|
`SET_DMAC_FLAGS_TLAST(flags[1])|
`SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(flags[2]));
`SET_DMAC_FLAGS_CYCLIC(flags[0]) |
`SET_DMAC_FLAGS_TLAST(flags[1]) |
`SET_DMAC_FLAGS_PARTIAL_REPORTING_EN(flags[2]));
endtask : set_flags

// -----------------
Expand Down Expand Up @@ -169,7 +192,7 @@ package dmac_api_pkg;
// -----------------
task transfer_start;
this.axi_write(GetAddrs(DMAC_TRANSFER_SUBMIT),
`SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1));
`SET_DMAC_TRANSFER_SUBMIT_TRANSFER_SUBMIT(1));
`INFO(("Transfer start"));
endtask : transfer_start

Expand All @@ -178,15 +201,15 @@ package dmac_api_pkg;
// -----------------
task set_dest_addr(input int xfer_addr);
this.axi_write(GetAddrs(DMAC_DEST_ADDRESS),
`SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(xfer_addr));
`SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(xfer_addr));
endtask : set_dest_addr

// -----------------
//
// -----------------
task set_src_addr(input int xfer_addr);
this.axi_write(GetAddrs(DMAC_SRC_ADDRESS),
`SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(xfer_addr));
`SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(xfer_addr));
endtask : set_src_addr

// -----------------
Expand All @@ -196,9 +219,9 @@ package dmac_api_pkg;
input int xfer_length_x,
input int xfer_length_y);
this.axi_write(GetAddrs(DMAC_X_LENGTH),
`SET_DMAC_X_LENGTH_X_LENGTH(xfer_length_x));
`SET_DMAC_X_LENGTH_X_LENGTH(xfer_length_x));
this.axi_write(GetAddrs(DMAC_Y_LENGTH),
`SET_DMAC_Y_LENGTH_Y_LENGTH(xfer_length_y));
`SET_DMAC_Y_LENGTH_Y_LENGTH(xfer_length_y));
endtask : set_lengths

// -----------------
Expand Down Expand Up @@ -275,6 +298,7 @@ package dmac_api_pkg;
output int next_transfer_id);

dma_2d_segment t_2d;
dma_flocked_2d_segment t_fl_2d;

wait_transfer_submission();
`INFO((" Submitting up a segment of : "));
Expand All @@ -286,14 +310,14 @@ package dmac_api_pkg;
end
if (p.DMA_TYPE_SRC == 0) begin
this.axi_write(GetAddrs(DMAC_SRC_ADDRESS),
`SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(t.src_addr));
`SET_DMAC_SRC_ADDRESS_SRC_ADDRESS(t.src_addr));
end
if (p.DMA_TYPE_DEST == 0) begin
this.axi_write(GetAddrs(DMAC_DEST_ADDRESS),
`SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(t.dst_addr));
`SET_DMAC_DEST_ADDRESS_DEST_ADDRESS(t.dst_addr));
end
this.axi_write(GetAddrs(DMAC_X_LENGTH),
`SET_DMAC_X_LENGTH_X_LENGTH(t.length-1));
`SET_DMAC_X_LENGTH_X_LENGTH(t.length-1));

if (p.DMA_2D_TRANSFER == 1) begin
if (!$cast(t_2d,t)) begin
Expand All @@ -304,17 +328,27 @@ package dmac_api_pkg;
t_2d.dst_stride = 0;
end
this.axi_write(GetAddrs(DMAC_Y_LENGTH),
`SET_DMAC_Y_LENGTH_Y_LENGTH(t_2d.ylength-1));
`SET_DMAC_Y_LENGTH_Y_LENGTH(t_2d.ylength-1));
if (p.DMA_TYPE_SRC == 0) begin
this.axi_write(GetAddrs(DMAC_SRC_STRIDE),
`SET_DMAC_SRC_STRIDE_SRC_STRIDE(t_2d.src_stride));
`SET_DMAC_SRC_STRIDE_SRC_STRIDE(t_2d.src_stride));
end
if (p.DMA_TYPE_DEST == 0) begin
this.axi_write(GetAddrs(DMAC_DEST_STRIDE),
`SET_DMAC_DEST_STRIDE_DEST_STRIDE(t_2d.dst_stride));
`SET_DMAC_DEST_STRIDE_DEST_STRIDE(t_2d.dst_stride));
end
end

if ($cast(t_fl_2d,t)) begin
this.axi_write(GetAddrs(DMAC_FRAMELOCK_CONFIG),
`SET_DMAC_FRAMELOCK_CONFIG_FRAMENUM(t_fl_2d.flock_framenum) |
`SET_DMAC_FRAMELOCK_CONFIG_MODE(t_fl_2d.flock_mode) |
`SET_DMAC_FRAMELOCK_CONFIG_WAIT_WRITER(t_fl_2d.flock_wait_writer ) |
`SET_DMAC_FRAMELOCK_CONFIG_DISTANCE(t_fl_2d.flock_distance-1));
this.axi_write(GetAddrs(DMAC_FRAMELOCK_STRIDE),
`SET_DMAC_FRAMELOCK_STRIDE_STRIDE(t_fl_2d.flock_stride));
end

transfer_id_get(next_transfer_id);
transfer_start();

Expand Down
Loading

0 comments on commit 2124530

Please sign in to comment.