3 Commits

Author SHA1 Message Date
Zhongdi LUO
4ec2099106 fix: select tensor DPU datatype at compile time 2026-07-13 07:47:47 +00:00
Zhongdi LUO
fb56e625bb feat: support 4-lane NVIDIA-style tensor cores 2026-07-13 07:20:29 +00:00
Zhongdi LUO
9560f9cab6 feat: support 4-lane pre-WU Blackwell RTL 2026-07-13 06:29:04 +00:00
5 changed files with 41 additions and 27 deletions

View File

@@ -82,7 +82,7 @@ module Vortex import VX_gpu_pkg::*; #(
output [2:0] tc_a_bits_write,
output [95:0] tc_a_bits_address,
output [3 * TC_TAG_WIDTH - 1:0] tc_a_bits_tag,
output [3 * 32 - 1:0] tc_a_bits_mask,
output [3 * (TC_DATA_WIDTH / 8) - 1:0] tc_a_bits_mask,
output [3 * TC_DATA_WIDTH - 1:0] tc_a_bits_data,
output [2:0] tc_d_ready,
input [2:0] tc_d_valid,

View File

@@ -33,9 +33,10 @@
`ifdef SYNTHESIS
`define NUM_BARRIERS 8
`define NUM_CORES 4
`define NUM_THREADS 8
`define NUM_WARPS 8
`define NUM_CORES 1
`define NUM_THREADS 4
`define NUM_WARPS 4
`define NVIDIA_STYLE_4LANE
`define FPU_FPNEW
// `define FIRESIM

View File

@@ -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:

View File

@@ -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),

View File

@@ -300,7 +300,7 @@ module VX_tensor_threadgroup #(
wire [31:0] d_col_sel = (substep_in == 1'b0) ? d_col : (d_col + 1);
// Dot product (FEDP) unit generated from Chisel
if (FP16 != 0) begin
`ifdef TENSOR_DPU_FP16
TensorDotProductUnit fedp (
.clock (clk),
.reset (reset),
@@ -318,7 +318,7 @@ module VX_tensor_threadgroup #(
.io_out_valid (fedp_valids[i]),
.io_out_bits_data (D_half[i])
);
end else begin
`else
TensorDotProductUnit fedp (
.clock (clk),
.reset (reset),
@@ -332,7 +332,7 @@ module VX_tensor_threadgroup #(
.io_out_valid (fedp_valids[i]),
.io_out_bits_data (D_half[i])
);
end
`endif
end
assign valid_out = fedp_valid_out && (substep_out == 1'b1);