/*
* 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 IM2COL_LOG2W_WIDTH =
$bits(datamover_regif_pkg::datamover_regif__dm_ctrl_engine__im2col_log2w__out_t);
// The im2col unit is instantiated when EnableIm2col is set on datamover_top.
parameter bit ENABLE_IM2COL = 1'b1;
// 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, 1 or 2
logic im2col_pack; // im2col: run the im2col unit
logic [IM2COL_LOG2W_WIDTH-1:0] im2col_log2w; // im2col unit: log2 of the image row width
datamover_mode_e datamover_mode;
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