diff --git a/hw/rtl/VX_platform.vh b/hw/rtl/VX_platform.vh index d07f7d6e..4a4f28c1 100644 --- a/hw/rtl/VX_platform.vh +++ b/hw/rtl/VX_platform.vh @@ -36,6 +36,7 @@ `define NUM_CORES 1 `define NUM_THREADS 4 `define NUM_WARPS 4 +`define NVIDIA_STYLE_4LANE `define FPU_FPNEW // `define FIRESIM diff --git a/hw/rtl/core/VX_tensor_core.sv b/hw/rtl/core/VX_tensor_core.sv index 3b95a4f1..434e4f2f 100644 --- a/hw/rtl/core/VX_tensor_core.sv +++ b/hw/rtl/core/VX_tensor_core.sv @@ -135,7 +135,7 @@ module VX_tensor_core_block import VX_gpu_pkg::*; #( VX_execute_if.slave execute_if, VX_commit_if.master commit_if ); - localparam NUM_OCTETS = (`NUM_THREADS / 8); + localparam NUM_OCTETS = (`NUM_THREADS == 4) ? 1 : (`NUM_THREADS / 8); // offet in the lane numbers that get mapped to the two threadgroups in an // octet. E.g. two tgs map lane 0-3 and lane 16-19 -> // LANE_OFFSET_THREADGROUP = 16 @@ -167,15 +167,24 @@ module VX_tensor_core_block import VX_gpu_pkg::*; #( for (genvar i = 0; i < 0; ++i) begin `endif // lane-to-octet mapping; see figure 13 of the paper - wire [7:0][31:0] octet_A = { - execute_if.data.rs1_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs1_data[4*i +: 4] - }; - wire [7:0][31:0] octet_B = { - execute_if.data.rs2_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs2_data[4*i +: 4] - }; - wire [7:0][31:0] octet_C = { - execute_if.data.rs3_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs3_data[4*i +: 4] - }; + wire [7:0][31:0] octet_A; + wire [7:0][31:0] octet_B; + wire [7:0][31:0] octet_C; + if (`NUM_THREADS == 4) begin : g_half_octet_inputs + assign octet_A = {execute_if.data.rs1_data[0 +: 4], execute_if.data.rs1_data[0 +: 4]}; + assign octet_B = {execute_if.data.rs2_data[0 +: 4], execute_if.data.rs2_data[0 +: 4]}; + assign octet_C = {execute_if.data.rs3_data[0 +: 4], execute_if.data.rs3_data[0 +: 4]}; + end else begin : g_full_octet_inputs + assign octet_A = { + execute_if.data.rs1_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs1_data[4*i +: 4] + }; + assign octet_B = { + execute_if.data.rs2_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs2_data[4*i +: 4] + }; + assign octet_C = { + execute_if.data.rs3_data[LANE_OFFSET_THREADGROUP + 4*i +: 4], execute_if.data.rs3_data[4*i +: 4] + }; + end wire [3:0][3:0][31:0] octet_D; wire result_valid; @@ -225,15 +234,17 @@ module VX_tensor_core_block import VX_gpu_pkg::*; #( assign wb_data_1[4*i+2] = octet_D[0][3]; assign wb_data_1[4*i+3] = octet_D[1][3]; - assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+0] = octet_D[2][0]; - assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+1] = octet_D[3][0]; - assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+2] = octet_D[2][2]; - assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+3] = octet_D[3][2]; + if (`NUM_THREADS >= 8) begin : g_second_threadgroup_writeback + assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+0] = octet_D[2][0]; + assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+1] = octet_D[3][0]; + assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+2] = octet_D[2][2]; + assign wb_data_0[4*i+LANE_OFFSET_THREADGROUP+3] = octet_D[3][2]; - assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+0] = octet_D[2][1]; - assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+1] = octet_D[3][1]; - assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+2] = octet_D[2][3]; - assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+3] = octet_D[3][3]; + assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+0] = octet_D[2][1]; + assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+1] = octet_D[3][1]; + assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+2] = octet_D[2][3]; + assign wb_data_1[4*i+LANE_OFFSET_THREADGROUP+3] = octet_D[3][3]; + end end /* commit_if.data_t parts that we need to keep around: diff --git a/hw/rtl/core/VX_tensor_hopper_core.sv b/hw/rtl/core/VX_tensor_hopper_core.sv index a88dccd9..9f43638d 100644 --- a/hw/rtl/core/VX_tensor_hopper_core.sv +++ b/hw/rtl/core/VX_tensor_hopper_core.sv @@ -109,8 +109,8 @@ module VX_tensor_hopper_core_block import VX_gpu_pkg::*; #( `STATIC_ASSERT((`INST_ALU_BITS == `INST_OP_BITS), ("static assertion failed: `INST_ALU_BITS != `INST_OP_BITS")) - `STATIC_ASSERT((`NUM_THREADS == 8), - ("static assertion failed: tensor_hopper_core only supports NUM_THREADS == 8")) + `STATIC_ASSERT(((`NUM_THREADS == 4) || (`NUM_THREADS == 8)), + ("static assertion failed: tensor_hopper_core only supports NUM_THREADS == 4 or 8")) `STATIC_ASSERT((`XLEN == 32), ("static assertion failed: tensor_hopper_core only supports XLEN == 32")) @@ -148,10 +148,12 @@ module VX_tensor_hopper_core_block import VX_gpu_pkg::*; #( .io_writeback_bits_data_1(writeback_data[1]), .io_writeback_bits_data_2(writeback_data[2]), .io_writeback_bits_data_3(writeback_data[3]), +`ifndef NVIDIA_STYLE_4LANE .io_writeback_bits_data_4(writeback_data[4]), .io_writeback_bits_data_5(writeback_data[5]), .io_writeback_bits_data_6(writeback_data[6]), .io_writeback_bits_data_7(writeback_data[7]), +`endif .io_respA_ready(smem_A_if.rsp_ready), .io_respA_valid(smem_A_if.rsp_valid),