/*
* datamover_package.sv
* Francesco Conti <f.conti@unibo.it>
*
* Copyright (C) 2019-2026 ETH Zurich, University of Bologna
* Copyright and related rights are licensed under the Solderpad Hardware
* License, Version 0.51 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
* or agreed to in writing, software, hardware and materials distributed under
* this License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
/*
* Authors: Francesco Conti <f.conti@unibo.it>
* Cyrill Durrer <cdurrer@iis.ee.ethz.ch>
*/
package datamover_package;
typedef struct packed {
hci_package::hci_streamer_ctrl_t data_in_source_ctrl;
hci_package::hci_streamer_ctrl_t data_out_sink_ctrl;
} ctrl_streamer_t;
typedef struct packed {
hci_package::hci_streamer_flags_t data_in_source_flags;
hci_package::hci_streamer_flags_t data_out_sink_flags;
logic tcdm_fifo_empty;
} flags_streamer_t;
parameter int unsigned MAX_BANDWIDTH = 512; // support maximum 512bits of bandwidth
// Widths of the job-dependent register fields generated by RDL
parameter int unsigned TENSOR_SIZE_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_matrix_dim__tensor_size_m__out_t);
parameter int unsigned TOTAL_ELEM_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_channels__total_elements__out_t);
parameter int unsigned NUM_CHANNELS_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_channels__num_channels__out_t);
parameter int unsigned CONV_STRIDE_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_ctrl_engine__conv_stride__out_t);
parameter int unsigned PACK_LOG2W_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_ctrl_engine__pack_log2w__out_t);
parameter int unsigned PACK_ROW_STRIDE_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_ctrl_engine__pack_row_stride__out_t);
// im2col padding
parameter int unsigned KERNEL_TAP_WIDTH = PACK_ROW_STRIDE_WIDTH / 2;
parameter int unsigned PACK_W_WIDTH = 1 << PACK_LOG2W_WIDTH;
// Element-granularity transpose steps by 1, 2 or 4 elements
parameter int unsigned MAX_TRANSP_STRIDE = 4;
parameter int unsigned TRANSP_STRIDE_WIDTH = $clog2(MAX_TRANSP_STRIDE) + 1;
// transp_len counts up to NB_ELEMENTS = BANDWIDTH_ALIGNED/ELEM_WIDTH inclusive.
parameter int unsigned TRANSP_LEN_WIDTH = $clog2(MAX_BANDWIDTH/8) + 1;
typedef enum logic[1:0] { TRANSP_NONE, TRANSP_1ELEM, TRANSP_2ELEM, TRANSP_4ELEM } transp_mode_e;
typedef enum logic[4:0] {
DATAMOVER_COPY, DATAMOVER_TRANSPOSE, DATAMOVER_CIM_CONVERSION, DATAMOVER_CIM_TRANSPOSE,
DATAMOVER_UNFOLD, DATAMOVER_FOLD, DATAMOVER_IM2COL
} datamover_mode_e;
typedef struct packed {
transp_mode_e transp_mode;
logic [TRANSP_LEN_WIDTH-1:0] transp_len;
logic [TRANSP_STRIDE_WIDTH-1:0] transp_stride; // 1, 2, or 4 elements
logic [CONV_STRIDE_WIDTH-1:0] conv_stride; // im2col column subsample factor (stride S)
logic im2col_pack; // im2col: pack sub-BW rows into dense beats
logic im2col_pad; // im2col: synthesize a 1-pixel zero border
logic [PACK_LOG2W_WIDTH-1:0] pack_log2w; // im2col packing: log2(w_out)
logic [PACK_ROW_STRIDE_WIDTH-1:0] pack_row_stride;// im2col packing: input row width W_pad
datamover_mode_e datamover_mode; // 0: copy, 1: transpose, 2: CIM layout
logic [TENSOR_SIZE_WIDTH-1:0] tensor_size_m;
logic [TENSOR_SIZE_WIDTH-1:0] tensor_size_n;
logic [TOTAL_ELEM_WIDTH-1:0] total_elements; // num_channels * size_m * size_n (from HAL)
logic [NUM_CHANNELS_WIDTH-1:0] num_channels; // number of channels (for unfolding/folding)
} ctrl_engine_t;
// Datamover job FSM states
typedef enum logic [1:0] { DM_IDLE, DM_STARTING, DM_WORKING, DM_FINISHED } datamover_state_e;
endpackage