// Copyright 2020-2023 Intel Corporation. // // This software and the related documents are Intel copyrighted materials, // and your use of them is governed by the express license under which they // were provided to you ("License"). Unless the License provides otherwise, // you may not use, modify, copy, publish, distribute, disclose or transmit // this software or the related documents without Intel's prior written // permission. // // This software and the related documents are provided as is, with no express // or implied warranties, other than those that are expressly stated in the // License. /* * Module `dla_aux_depthwise_group` * * Group wrapper of the auxiliary block. * * WARNING! DO NOT EDIT THIS FILE FOR FUTURE-COMPATIBILITY * * This module is a template for all auxiliary blocks and the content should * not be modified for future compatibility. * * Do not modify any of fields other than the module name and included package * name. In case of a limitation or bug please contact owner of the Example * Aux block. * * See README.md of the Example Aux block for more details. */ `undefineall `resetall `default_nettype none `include "dla_acl_parameter_assert.svh" module dla_aux_depthwise_group import dla_aux_depthwise_pkg::*; #( parameter int ID, // Unique ID of the group parameter aux_depthwise_arch_params_t ARCH, // Architecture parameters parameter vector_dot_arch_t AUX_DEPTHWISE_VECTOR_ARCH, parameter vector_dot_arch_info_t DEPTHWISE_VECTOR_ARCH_INFO ) ( input wire clk , // Clock input wire i_resetn , // Active-low sync reset // input var logic [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.ELEMENT_BITS-1:0] i_data , // Data input stream port input var logic i_data_valid , // Data input stream port valid output generic_response_t o_data , // Data input response // input generic_response_t i_result , // Result output response output logic [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.ELEMENT_BITS-1:0] o_result , // Result output stream port output logic o_result_valid , // Result output stream port valid // input wire [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [ARCH.AUX_SPECIAL_PARAMS.MAX_WINDOW_HEIGHT*ARCH.AUX_SPECIAL_PARAMS.MAX_WINDOW_WIDTH-1:0] [ARCH.AUX_DATA_PACK_PARAMS.ELEMENT_BITS-1:0] i_filter, input wire [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [AUX_DEPTHWISE_VECTOR_ARCH.BIAS_WIDTH-1:0] i_bias, // fp32 bias // depthwise_config_to_control_if.receiver i_config_to_control , // Config to control port output control_to_config_t o_control_to_config , // Control to config port // depthwise_control_to_lane_if.receiver i_control_to_lane , // (global control input) depthwise_control_to_lane_if.sender o_control_to_lane_next, // the next group of lanes // input var logic i_config_filter_bias_valid, // Config (actual data) for cache input var logic [31:0] i_config_filter_bias_data, output var logic o_config_filter_bias_ready, output debug_group_t o_debug // Debug output ); /* synthesis translate_off */ `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_data_pack_params_t'(i_config_to_control.data_pack_params) == ARCH.AUX_DATA_PACK_PARAMS, "i_config_to_control if parameters don't match data pack params") `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_special_params_t'(i_config_to_control.special_params) == ARCH.AUX_SPECIAL_PARAMS, "i_config_to_control if parameters don't match special params") `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_data_pack_params_t'(i_control_to_lane.data_pack_params) == ARCH.AUX_DATA_PACK_PARAMS, "i_control_to_lane if parameters don't match data pack params") `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_special_params_t'(i_control_to_lane.special_params) == ARCH.AUX_SPECIAL_PARAMS, "i_control_to_lane if parameters don't match special params") `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_data_pack_params_t'(o_control_to_lane_next.data_pack_params) == ARCH.AUX_DATA_PACK_PARAMS, "o_control_to_lane_next if parameters don't match data pack params") `DLA_ACL_PARAMETER_ASSERT_MESSAGE(aux_special_params_t'(o_control_to_lane_next.special_params) == ARCH.AUX_SPECIAL_PARAMS, "o_control_to_lane_next if parameters don't match special params") /* synthesis translate_on */ logic [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.ELEMENT_BITS-1:0] data [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE]; logic data_valid [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE]; logic [ARCH.AUX_DATA_PACK_PARAMS.VECTOR_SIZE-1:0] [ARCH.AUX_DATA_PACK_PARAMS.ELEMENT_BITS-1:0] result [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE]; logic result_valid [ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE]; depthwise_control_to_lane_if #( .special_params (ARCH.AUX_SPECIAL_PARAMS ), .data_pack_params(ARCH.AUX_DATA_PACK_PARAMS)) control_to_lane(); lane_to_control_t lane_to_control; debug_control_t debug_from_control; debug_lane_t debug_from_lane ; for (genvar i = 0; i < ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE; i++) begin : gen_stream_lane // Input data port's valid signal is distributed to all lanes assign data_valid[i] = i_data_valid ; // Input data port's data signal is uncombined per lane assign data[i] = i_data[i]; // All lanes' results are combined at the result output assign o_result[i] = result[i]; end : gen_stream_lane // Only first lane's result port's valid signal is relayed to the output assign o_result_valid = result_valid[0]; // If this is the first group or per-group control is enabled, then ignore the control input and // implement the control sub-block instead. Otherwise, control input is used. if (ID == 0 || ARCH.AUX_GENERIC_PARAMS.PER_GROUP_CONTROL) begin : gen_control_group dla_aux_depthwise_control #( .ARCH(ARCH) ) dla_aux_depthwise_control_inst ( .clk (clk ), .i_resetn (i_resetn ), .i_config_to_control(i_config_to_control), .o_control_to_config(o_control_to_config), .o_control_to_lane (control_to_lane ), .i_lane_to_control (lane_to_control ), .o_debug (debug_from_control ) ); end : gen_control_group else begin : gen_control_bypass assign control_to_lane.data[0][0] = i_control_to_lane.data[0][0]; end : gen_control_bypass // Bypassed to the control interface to the control output. assign o_control_to_lane_next.data[0][0] = control_to_lane.data[0][0]; // First lane is instantiated separately since it needs to communicate with the control block and // also generate debug information. The rest of the lanes are clones and do not interact with // other sub-blocks. dla_aux_depthwise_lane #( .ID (ID ), .ARCH(ARCH), .AUX_DEPTHWISE_VECTOR_ARCH(AUX_DEPTHWISE_VECTOR_ARCH), .DEPTHWISE_VECTOR_ARCH_INFO(DEPTHWISE_VECTOR_ARCH_INFO) ) dla_aux_depthwise_lane_inst ( .clk (clk ), .i_resetn (i_resetn ), .i_data (data [0]), .i_data_valid (data_valid [0]), .o_data (o_data ), .i_result (i_result ), .o_result (result [0]), .o_result_valid (result_valid [0]), .i_filter (i_filter ), .i_bias (i_bias ), .i_config_filter_bias_valid (i_config_filter_bias_valid), .i_config_filter_bias_data (i_config_filter_bias_data), .o_config_filter_bias_ready (o_config_filter_bias_ready), .i_control_to_lane(control_to_lane ), .o_lane_to_control(lane_to_control ), .o_debug (debug_from_lane ) ); for (genvar i = 1; i < ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE; i++) begin : gen_lanes dla_aux_depthwise_lane #( .ID (ARCH.AUX_DATA_PACK_PARAMS.GROUP_SIZE * ID + i), .ARCH(ARCH ) ) dla_aux_depthwise_lane_inst ( .clk (clk ), .i_resetn (i_resetn ), .i_data (data [i]), .i_data_valid (data_valid [i]), .o_data ( ), .i_result (i_result ), .o_result (result [i]), .o_result_valid (result_valid [i]), .i_filter (i_filter ), .i_bias (i_bias ), .i_config_filter_bias_valid (i_config_filter_bias_valid), .i_config_filter_bias_data (i_config_filter_bias_data), .o_config_filter_bias_ready (o_config_filter_bias_ready), .i_control_to_lane(control_to_lane ), .o_lane_to_control( ), .o_debug ( ) ); end : gen_lanes assign o_debug = '{ control : debug_from_control, lane : debug_from_lane }; endmodule