// ================================================================ // NVDLA Open Source Project // // Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the // NVDLA Open Hardware License; Check "LICENSE" which comes with // this distribution for more information. // ================================================================ // File Name: NV_NVDLA_SDP_RDMA_ig.v `include "simulate_x_tick.vh" // ================================================================ // NVDLA Open Source Project // // Copyright(c) 2016 - 2017 NVIDIA Corporation. Licensed under the // NVDLA Open Hardware License; Check "LICENSE" which comes with // this distribution for more information. // ================================================================ // File Name: NV_NVDLA_SDP_define.h module NV_NVDLA_SDP_RDMA_ig ( nvdla_core_clk ,nvdla_core_rstn ,op_load ,ig2cq_pd ,ig2cq_pvld ,ig2cq_prdy ,dma_rd_req_pd ,dma_rd_req_vld ,dma_rd_req_rdy ,reg2dp_op_en ,reg2dp_winograd ,reg2dp_channel ,reg2dp_height ,reg2dp_width ,reg2dp_rdma_data_mode ,reg2dp_rdma_data_size ,reg2dp_rdma_data_use ,reg2dp_base_addr_high ,reg2dp_base_addr_low ,reg2dp_line_stride ,reg2dp_surface_stride ,reg2dp_proc_precision ,reg2dp_perf_dma_en ,dp2reg_rdma_stall ); input nvdla_core_clk; input nvdla_core_rstn; input op_load; input dma_rd_req_rdy; output [47 -1:0] dma_rd_req_pd; output dma_rd_req_vld; input ig2cq_prdy; output [15:0] ig2cq_pd; output ig2cq_pvld; input reg2dp_op_en; input reg2dp_winograd; input [12:0] reg2dp_channel; input [12:0] reg2dp_height; input [12:0] reg2dp_width; input [1:0] reg2dp_proc_precision; input reg2dp_rdma_data_mode; input reg2dp_rdma_data_size; input [1:0] reg2dp_rdma_data_use; input [31:0] reg2dp_base_addr_high; input [31-3:0] reg2dp_base_addr_low; input [31-3:0] reg2dp_line_stride; input [31-3:0] reg2dp_surface_stride; input reg2dp_perf_dma_en; output [31:0] dp2reg_rdma_stall; reg [32 -3 -1:0] base_addr_line; reg [32 -3 -1:0] base_addr_surf; reg [32 -3 -1:0] base_addr_width; reg mon_base_addr_line_c; reg mon_base_addr_surf_c; reg mon_base_addr_width_c; wire ig2eg_cube_end; wire [14:0] ig2eg_size; reg cmd_process; wire cmd_accept; wire op_done; reg [13-3:0] count_c; reg [14:0] count_w; reg [12:0] count_h; reg [13-3:0] size_of_surf; reg [14:0] size_of_straight; reg [14:0] size_of_width; wire [12:0] size_of_height; wire [32 -3 -1:0] cfg_base_addr; wire cfg_data_mode_per_kernel; wire cfg_data_size_1byte; wire cfg_data_use_both; wire cfg_mode_1x1_pack; wire cfg_proc_int16; wire cfg_proc_int8; wire [31-3:0] cfg_line_stride; wire [31-3:0] cfg_surf_stride; wire is_cube_end; wire is_last_c; wire is_last_h; wire is_last_w; wire is_line_end; wire is_surf_end; reg [14:0] dma_req_size; reg [32 -1:0] dma_req_addr; reg stl_adv; reg [31:0] stl_cnt_cur; reg [33:0] stl_cnt_dec; reg [33:0] stl_cnt_ext; reg [33:0] stl_cnt_inc; reg [33:0] stl_cnt_mod; reg [33:0] stl_cnt_new; reg [33:0] stl_cnt_nxt; wire rdma_stall_cnt_cen; wire rdma_stall_cnt_clr; wire rdma_stall_cnt_inc; wire dp2reg_rdma_stall_dec; reg [31:0] dp2reg_rdma_stall; assign op_done = cmd_accept & is_cube_end; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin cmd_process <= 1'b0; end else begin if (op_load) begin cmd_process <= 1'b1; end else if (op_done) begin cmd_process <= 1'b0; end end end `ifdef SPYGLASS_ASSERT_ON `else // spyglass disable_block NoWidthInBasedNum-ML // spyglass disable_block STARC-2.10.3.2a // spyglass disable_block STARC05-2.1.3.1 // spyglass disable_block STARC-2.1.4.6 // spyglass disable_block W116 // spyglass disable_block W154 // spyglass disable_block W239 // spyglass disable_block W362 // spyglass disable_block WRN_58 // spyglass disable_block WRN_61 `endif // SPYGLASS_ASSERT_ON `ifdef ASSERT_ON `ifdef FV_ASSERT_ON `define ASSERT_RESET nvdla_core_rstn `else `ifdef SYNTHESIS `define ASSERT_RESET nvdla_core_rstn `else `ifdef ASSERT_OFF_RESET_IS_X `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn) `else `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn) `endif // ASSERT_OFF_RESET_IS_X `endif // SYNTHESIS `endif // FV_ASSERT_ON // VCS coverage off nv_assert_never #(0,0,"SDP-RDMA: get an op-done without starting the op") zzz_assert_never_1x (nvdla_core_clk, `ASSERT_RESET, !cmd_process && op_done); // spyglass disable W504 SelfDeterminedExpr-ML // VCS coverage on `undef ASSERT_RESET `endif // ASSERT_ON `ifdef SPYGLASS_ASSERT_ON `else // spyglass enable_block NoWidthInBasedNum-ML // spyglass enable_block STARC-2.10.3.2a // spyglass enable_block STARC05-2.1.3.1 // spyglass enable_block STARC-2.1.4.6 // spyglass enable_block W116 // spyglass enable_block W154 // spyglass enable_block W239 // spyglass enable_block W362 // spyglass enable_block WRN_58 // spyglass enable_block WRN_61 `endif // SPYGLASS_ASSERT_ON //============== // Address catenate and offset calc //============== assign cfg_base_addr = reg2dp_base_addr_low; assign cfg_surf_stride = {reg2dp_surface_stride}; assign cfg_line_stride = {reg2dp_line_stride}; assign cfg_data_size_1byte = reg2dp_rdma_data_size == 1'h0 ; assign cfg_data_use_both = reg2dp_rdma_data_use == 2'h2 ; assign cfg_data_mode_per_kernel = reg2dp_rdma_data_mode == 1'h0 ; assign cfg_proc_int8 = reg2dp_proc_precision == 0 ; assign cfg_proc_int16 = reg2dp_proc_precision == 1 ; assign cfg_mode_1x1_pack = (reg2dp_width==0) & (reg2dp_height==0); //================================================= // Cube Shape //================================================= assign is_line_end = 1'b1; assign is_surf_end = cfg_mode_1x1_pack | cfg_data_mode_per_kernel | (is_line_end & is_last_h); assign is_cube_end = cfg_mode_1x1_pack | cfg_data_mode_per_kernel | (is_surf_end & is_last_c); //============== // CHANNEL Count: //============== always @( cfg_proc_int8 or reg2dp_channel or cfg_proc_int16 ) begin if (cfg_proc_int8) begin size_of_surf = {1'b0,reg2dp_channel[12:3]}; end else if (cfg_proc_int16) begin size_of_surf = reg2dp_channel[12:3 -1]; end else begin size_of_surf = reg2dp_channel[12:3 -1]; end end always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin count_c <= {(14-3){1'b0}}; end else begin if (cmd_accept) begin if (is_cube_end) begin count_c <= 0; end else if (is_surf_end) begin count_c <= count_c + 1; end end end end assign is_last_c = (count_c==size_of_surf); //============== // HEIGHT Count: //============== assign size_of_height = reg2dp_height; always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin count_h <= {13{1'b0}}; end else begin if (cmd_accept) begin if (is_surf_end) begin count_h <= 0; end else if (is_line_end) begin count_h <= count_h + 1; end end end end assign is_last_h = (count_h==size_of_height); //========================================== // DMA Req : ADDR PREPARE //========================================== // LINE always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin base_addr_line <= {(32 -3){1'b0}}; mon_base_addr_line_c <= 1'b0; end else begin if (op_load) begin base_addr_line <= cfg_base_addr; end else if (cmd_accept) begin begin if (is_surf_end) begin {mon_base_addr_line_c,base_addr_line} <= base_addr_surf + cfg_surf_stride; end else begin {mon_base_addr_line_c,base_addr_line} <= base_addr_line + cfg_line_stride; end end end end end `ifdef SPYGLASS_ASSERT_ON `else // spyglass disable_block NoWidthInBasedNum-ML // spyglass disable_block STARC-2.10.3.2a // spyglass disable_block STARC05-2.1.3.1 // spyglass disable_block STARC-2.1.4.6 // spyglass disable_block W116 // spyglass disable_block W154 // spyglass disable_block W239 // spyglass disable_block W362 // spyglass disable_block WRN_58 // spyglass disable_block WRN_61 `endif // SPYGLASS_ASSERT_ON `ifdef ASSERT_ON `ifdef FV_ASSERT_ON `define ASSERT_RESET nvdla_core_rstn `else `ifdef SYNTHESIS `define ASSERT_RESET nvdla_core_rstn `else `ifdef ASSERT_OFF_RESET_IS_X `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn) `else `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn) `endif // ASSERT_OFF_RESET_IS_X `endif // SYNTHESIS `endif // FV_ASSERT_ON // VCS coverage off nv_assert_never #(0,0,"SDP RDMA: no overflow is allowed") zzz_assert_never_2x (nvdla_core_clk, `ASSERT_RESET, mon_base_addr_line_c); // spyglass disable W504 SelfDeterminedExpr-ML // VCS coverage on `undef ASSERT_RESET `endif // ASSERT_ON `ifdef SPYGLASS_ASSERT_ON `else // spyglass enable_block NoWidthInBasedNum-ML // spyglass enable_block STARC-2.10.3.2a // spyglass enable_block STARC05-2.1.3.1 // spyglass enable_block STARC-2.1.4.6 // spyglass enable_block W116 // spyglass enable_block W154 // spyglass enable_block W239 // spyglass enable_block W362 // spyglass enable_block WRN_58 // spyglass enable_block WRN_61 `endif // SPYGLASS_ASSERT_ON // SURF always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin base_addr_surf <= {(32 -3){1'b0}}; mon_base_addr_surf_c <= 1'b0; end else begin if (op_load) begin base_addr_surf <= cfg_base_addr; end else if (cmd_accept) begin begin if (is_surf_end) begin {mon_base_addr_surf_c,base_addr_surf} <= base_addr_surf + cfg_surf_stride; end end end end end `ifdef SPYGLASS_ASSERT_ON `else // spyglass disable_block NoWidthInBasedNum-ML // spyglass disable_block STARC-2.10.3.2a // spyglass disable_block STARC05-2.1.3.1 // spyglass disable_block STARC-2.1.4.6 // spyglass disable_block W116 // spyglass disable_block W154 // spyglass disable_block W239 // spyglass disable_block W362 // spyglass disable_block WRN_58 // spyglass disable_block WRN_61 `endif // SPYGLASS_ASSERT_ON `ifdef ASSERT_ON `ifdef FV_ASSERT_ON `define ASSERT_RESET nvdla_core_rstn `else `ifdef SYNTHESIS `define ASSERT_RESET nvdla_core_rstn `else `ifdef ASSERT_OFF_RESET_IS_X `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn) `else `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn) `endif // ASSERT_OFF_RESET_IS_X `endif // SYNTHESIS `endif // FV_ASSERT_ON // VCS coverage off nv_assert_never #(0,0,"SDP RDMA: no overflow is allowed") zzz_assert_never_3x (nvdla_core_clk, `ASSERT_RESET, mon_base_addr_surf_c); // spyglass disable W504 SelfDeterminedExpr-ML // VCS coverage on `undef ASSERT_RESET `endif // ASSERT_ON `ifdef SPYGLASS_ASSERT_ON `else // spyglass enable_block NoWidthInBasedNum-ML // spyglass enable_block STARC-2.10.3.2a // spyglass enable_block STARC05-2.1.3.1 // spyglass enable_block STARC-2.1.4.6 // spyglass enable_block W116 // spyglass enable_block W154 // spyglass enable_block W239 // spyglass enable_block W362 // spyglass enable_block WRN_58 // spyglass enable_block WRN_61 `endif // SPYGLASS_ASSERT_ON //========================================== // DMA Req : Addr //========================================== always @( base_addr_line ) begin dma_req_addr = {base_addr_line,{3{1'b0}}}; end // Size_Of_Width: As each element is 1B or 2B, the width of cube will be resized accordingly always @( reg2dp_width or cfg_proc_int8 or cfg_data_use_both or cfg_data_size_1byte ) begin if (cfg_proc_int8) begin if (cfg_data_use_both) begin if (cfg_data_size_1byte) begin size_of_width = (reg2dp_width << 1) + 1; end else begin size_of_width = (reg2dp_width << 2) + 3; end end else begin if (cfg_data_size_1byte) begin size_of_width = {2'd0,reg2dp_width}; end else begin size_of_width = (reg2dp_width << 1) + 1; end end end else begin if (cfg_data_use_both) begin size_of_width = (reg2dp_width << 1) + 1; end else begin size_of_width = {2'd0,reg2dp_width}; end end end //========================================== // DMA Req : SIZE //========================================== // in 1x1_pack mode, only send one request out //assign mode_1x1_req_size = size_of_surf; // PRECISION: 2byte both // 8:1byte:single - 1B/elem - 32B/surf - 1 x surf // 8:2byte:single - 2B/elem - 64B/surf - 2 x surf // 8:1byte:both - 2B/elem - 64B/surf - 2 x surf // 8:2byte:both - 4B/elem - 128B/surf - 4 x surf // 16:2byte:single - 2B/elem - 32B/surf - 1 x surf // 16:2byte:both - 4B/elem - 64B/surf - 2 x surf always @( cfg_proc_int8 or cfg_data_use_both or cfg_data_size_1byte or size_of_surf ) begin if (cfg_proc_int8) begin if (cfg_data_use_both) begin if (cfg_data_size_1byte) begin size_of_straight = (size_of_surf << 1) + 1; end else begin size_of_straight = (size_of_surf << 2) + 3; end end else begin if (cfg_data_size_1byte) begin size_of_straight = (size_of_surf << 0) + 0; end else begin size_of_straight = (size_of_surf << 1) + 1; end end end else begin if (cfg_data_use_both) begin if (cfg_data_size_1byte) begin size_of_straight = (size_of_surf << 1) + 0; // illegal end else begin size_of_straight = (size_of_surf << 1) + 1; end end else begin if (cfg_data_size_1byte) begin size_of_straight = (size_of_surf << 1) + 0; // illegal end else begin size_of_straight = (size_of_surf << 0) + 0; end end end end `ifdef SPYGLASS_ASSERT_ON `else // spyglass disable_block NoWidthInBasedNum-ML // spyglass disable_block STARC-2.10.3.2a // spyglass disable_block STARC05-2.1.3.1 // spyglass disable_block STARC-2.1.4.6 // spyglass disable_block W116 // spyglass disable_block W154 // spyglass disable_block W239 // spyglass disable_block W362 // spyglass disable_block WRN_58 // spyglass disable_block WRN_61 `endif // SPYGLASS_ASSERT_ON `ifdef ASSERT_ON `ifdef FV_ASSERT_ON `define ASSERT_RESET nvdla_core_rstn `else `ifdef SYNTHESIS `define ASSERT_RESET nvdla_core_rstn `else `ifdef ASSERT_OFF_RESET_IS_X `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn) `else `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn) `endif // ASSERT_OFF_RESET_IS_X `endif // SYNTHESIS `endif // FV_ASSERT_ON // VCS coverage off nv_assert_never #(0,0,"NO SIZE of 1Byte supported if proc precision is INT16") zzz_assert_never_6x (nvdla_core_clk, `ASSERT_RESET, reg2dp_op_en & cfg_proc_int16 & cfg_data_size_1byte); // spyglass disable W504 SelfDeterminedExpr-ML // VCS coverage on `undef ASSERT_RESET `endif // ASSERT_ON `ifdef SPYGLASS_ASSERT_ON `else // spyglass enable_block NoWidthInBasedNum-ML // spyglass enable_block STARC-2.10.3.2a // spyglass enable_block STARC05-2.1.3.1 // spyglass enable_block STARC-2.1.4.6 // spyglass enable_block W116 // spyglass enable_block W154 // spyglass enable_block W239 // spyglass enable_block W362 // spyglass enable_block WRN_58 // spyglass enable_block WRN_61 `endif // SPYGLASS_ASSERT_ON always @( cfg_data_mode_per_kernel or cfg_mode_1x1_pack or size_of_straight or size_of_width ) begin if (cfg_data_mode_per_kernel || cfg_mode_1x1_pack) begin dma_req_size = size_of_straight; end else begin begin dma_req_size = size_of_width; end end end //========================================== // Context Queue Interface // size,cube_end //========================================== assign ig2eg_size = dma_req_size; assign ig2eg_cube_end = is_cube_end; assign ig2cq_pd[14:0] = ig2eg_size[14:0]; assign ig2cq_pd[15] = ig2eg_cube_end ; assign ig2cq_pvld = cmd_process & dma_rd_req_rdy; `ifdef SPYGLASS_ASSERT_ON `else // spyglass disable_block NoWidthInBasedNum-ML // spyglass disable_block STARC-2.10.3.2a // spyglass disable_block STARC05-2.1.3.1 // spyglass disable_block STARC-2.1.4.6 // spyglass disable_block W116 // spyglass disable_block W154 // spyglass disable_block W239 // spyglass disable_block W362 // spyglass disable_block WRN_58 // spyglass disable_block WRN_61 `endif // SPYGLASS_ASSERT_ON `ifdef ASSERT_ON `ifdef FV_ASSERT_ON `define ASSERT_RESET nvdla_core_rstn `else `ifdef SYNTHESIS `define ASSERT_RESET nvdla_core_rstn `else `ifdef ASSERT_OFF_RESET_IS_X `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b0 : nvdla_core_rstn) `else `define ASSERT_RESET ((1'bx === nvdla_core_rstn) ? 1'b1 : nvdla_core_rstn) `endif // ASSERT_OFF_RESET_IS_X `endif // SYNTHESIS `endif // FV_ASSERT_ON // VCS coverage off nv_assert_never #(0,0,"SDP-RDMA: CQ and DMA should accept or reject together") zzz_assert_never_7x (nvdla_core_clk, `ASSERT_RESET, (ig2cq_pvld & ig2cq_prdy) ^ (dma_rd_req_vld & dma_rd_req_rdy)); // spyglass disable W504 SelfDeterminedExpr-ML // VCS coverage on `undef ASSERT_RESET `endif // ASSERT_ON `ifdef SPYGLASS_ASSERT_ON `else // spyglass enable_block NoWidthInBasedNum-ML // spyglass enable_block STARC-2.10.3.2a // spyglass enable_block STARC05-2.1.3.1 // spyglass enable_block STARC-2.1.4.6 // spyglass enable_block W116 // spyglass enable_block W154 // spyglass enable_block W239 // spyglass enable_block W362 // spyglass enable_block WRN_58 // spyglass enable_block WRN_61 `endif // SPYGLASS_ASSERT_ON //============== // DMA Req : PIPE //============== // VALID: clamp when when cq is not ready assign dma_rd_req_vld = cmd_process & ig2cq_prdy; assign dma_rd_req_pd[32 -1:0] = dma_req_addr[32 -1:0]; assign dma_rd_req_pd[47 -1:32] = dma_req_size[14:0]; // Accept assign cmd_accept = dma_rd_req_vld & dma_rd_req_rdy; //============== // PERF STATISTIC assign rdma_stall_cnt_inc = dma_rd_req_vld & !dma_rd_req_rdy; assign rdma_stall_cnt_clr = op_load; assign rdma_stall_cnt_cen = reg2dp_op_en & reg2dp_perf_dma_en; assign dp2reg_rdma_stall_dec = 1'b0; // stl adv logic always @( rdma_stall_cnt_inc or dp2reg_rdma_stall_dec ) begin stl_adv = rdma_stall_cnt_inc ^ dp2reg_rdma_stall_dec; end // stl cnt logic always @( stl_cnt_cur or rdma_stall_cnt_inc or dp2reg_rdma_stall_dec or stl_adv or rdma_stall_cnt_clr ) begin stl_cnt_ext[33:0] = {1'b0, 1'b0, stl_cnt_cur}; stl_cnt_inc[33:0] = stl_cnt_cur + 1'b1; stl_cnt_dec[33:0] = stl_cnt_cur - 1'b1; stl_cnt_mod[33:0] = (rdma_stall_cnt_inc && !dp2reg_rdma_stall_dec)? stl_cnt_inc : (!rdma_stall_cnt_inc && dp2reg_rdma_stall_dec)? stl_cnt_dec : stl_cnt_ext; stl_cnt_new[33:0] = (stl_adv)? stl_cnt_mod[33:0] : stl_cnt_ext[33:0]; stl_cnt_nxt[33:0] = (rdma_stall_cnt_clr)? 34'd0 : stl_cnt_new[33:0]; end // stl flops always @(posedge nvdla_core_clk or negedge nvdla_core_rstn) begin if (!nvdla_core_rstn) begin stl_cnt_cur[31:0] <= 0; end else begin if (rdma_stall_cnt_cen) begin stl_cnt_cur[31:0] <= stl_cnt_nxt[31:0]; end end end // stl output logic always @( stl_cnt_cur ) begin dp2reg_rdma_stall[31:0] = stl_cnt_cur[31:0]; end endmodule // NV_NVDLA_SDP_RDMA_ig