Vengineerの妄想

人生を妄想しています。

RISC-VなGPGPUであるVortexを深堀する (その4)

はじめに

RISC-VなGPGPUであるVortexを深堀する (その4)として、SIMT な部分と WARP な部分を実装している部分をみていきます。

VX_dispatch

VX_dispatch は、VX_issue の中に下記のようにインスタンスされています。

    VX_dispatch dispatch (
        .clk        (clk),      
        .reset      (dispatch_reset),
        .ibuffer_if (dispatch_if),
        .gpr_rsp_if (gpr_rsp_if),
        .alu_req_if (alu_req_if),
        .lsu_req_if (lsu_req_if),        
        .csr_req_if (csr_req_if),
    `ifdef EXT_F_ENABLE
        .fpu_req_if (fpu_req_if),
    `endif
        .gpu_req_if (gpu_req_if)
    );

VX_dispatch の中の、VX_lzc の cnt_o が Thread (tid) になっています

    VX_lzc #(
        .N (`NUM_THREADS)
    ) tid_select (
        .in_i       (ibuffer_if.tmask),
        .cnt_o      (tid),
        `UNUSED_PIN (valid_o)
    );

この tid が SIMT なポイントです。tid が使われているのは、

tid => alu_req_if.tid

    wire [31:0] csr_rs1_data = gpr_rsp_if.rs1_data[tid];

です。GPR と ALU を選択するために使っているようです。

VX_alu_unit の 下記の部分で、alu_req.tid が使われています。

    wire [31:0] br_dest    = add_result[alu_req_if.tid]; 
    wire [32:0] cmp_result = sub_result[alu_req_if.tid];   

WARP な部分は?

WARP な部分は、VX_warp_sched ですね。Thread の tid と同じように VX_lzc を使っていますね。

    VX_lzc #(
        .N (`NUM_WARPS)
    ) wid_select (
        .in_i    (ready_warps),
        .cnt_o   (schedule_wid),
        .valid_o (schedule_valid)
    );

下記のコードで、schedule_tmask と scedule_pc を得ています。

    assign {schedule_tmask, schedule_pc} = schedule_data[schedule_wid];

schedule_tmask と scedule_pc は、最終的に、ifetch_req_if.tmask と ifetch_req_if.PC になっています。

    VX_pipe_register #( 
        .DATAW  (1 + `UUID_BITS + `NUM_THREADS + 32 + `NW_BITS),
        .RESETW (1)
    ) pipe_reg (
        .clk      (clk),
        .reset    (reset),
        .enable   (!stall_out),
        .data_in  ({schedule_valid,      instr_uuid,         schedule_tmask,      schedule_pc,      schedule_wid}),
        .data_out ({ifetch_req_if.valid, ifetch_req_if.uuid, ifetch_req_if.tmask, ifetch_req_if.PC, ifetch_req_if.wid})
    );

ifetch_req_if は、VX_icache_stage に接続して、I-Cache に繋がっています。

    VX_icache_stage #(
        .CORE_ID(CORE_ID)
    ) icache_stage (
        `SCOPE_BIND_VX_fetch_icache_stage

        .clk            (clk),
        .reset          (reset),        
        
        .icache_rsp_if  (icache_rsp_if),
        .icache_req_if  (icache_req_if),

        .ifetch_req_if  (ifetch_req_if),
        .ifetch_rsp_if  (ifetch_rsp_if)   
    );

おわりに

次回は、RISC-VなGPGPUである Vortex を深堀する (その5)として、Vortex の runtime をみてみます。