feat: support 4-lane NVIDIA-style tensor cores
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user