Vengineerの妄想

人生を妄想しています。

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

はじめに

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

今回は、Vortex のコア (VX_core)を見ていきます。下図の上の部分に対応します。

core : VX_core

VX_core.sv の中には、下記の2つのブロックがインスタンスされています。

  • VX_pipeline
  • VX_mem_unit

VX_pipeline

VX_pipeline では、I-CacheとD-Cacheのインタフェースがあります。

    VX_pipeline #(
        .CORE_ID(CORE_ID)
    ) pipeline (
        `SCOPE_BIND_VX_core_pipeline
    `ifdef PERF_ENABLE
        .perf_memsys_if (perf_memsys_if),
    `endif

        .clk(clk),
        .reset(reset),

        // Dcache core request
        .dcache_req_valid   (dcache_req_if.valid),
        .dcache_req_rw      (dcache_req_if.rw),
        .dcache_req_byteen  (dcache_req_if.byteen),
        .dcache_req_addr    (dcache_req_if.addr),
        .dcache_req_data    (dcache_req_if.data),
        .dcache_req_tag     (dcache_req_if.tag),
        .dcache_req_ready   (dcache_req_if.ready),

        // Dcache core reponse    
        .dcache_rsp_valid   (dcache_rsp_if.valid),
        .dcache_rsp_tmask   (dcache_rsp_if.tmask),
        .dcache_rsp_data    (dcache_rsp_if.data),
        .dcache_rsp_tag     (dcache_rsp_if.tag),
        .dcache_rsp_ready   (dcache_rsp_if.ready),

        // Icache core request
        .icache_req_valid   (icache_req_if.valid),
        .icache_req_addr    (icache_req_if.addr),
        .icache_req_tag     (icache_req_if.tag),
        .icache_req_ready   (icache_req_if.ready),

        // Icache core reponse    
        .icache_rsp_valid   (icache_rsp_if.valid),
        .icache_rsp_data    (icache_rsp_if.data),
        .icache_rsp_tag     (icache_rsp_if.tag),
        .icache_rsp_ready   (icache_rsp_if.ready),

        // Status
        .busy(busy)
    );  

VX_pipeline には、

  • VX_fetch
  • VX_decode
  • VX_issue
  • VX_execute
  • VX_commit

インスタンスされています。上記の図に対応しています。

VX_fetch

VX_fetch には、

  • VX_warp_sched
  • VX_icache_stage

インスタンスされています。下図の灰色の部分に対応しているっぽいです。

Instruction Cacheはこの階層ではなく、VX_core 内の VX_mem_unit にあります。

つまり、ICache Stage と Instruction Cache 以外は、VX_warp_sched の中に実装されています。

VX_decode

VX_decode では、Fetch した命令をデコードしています。

デコード部分は、命令を下記のように分離しています。

  • INST_I
  • INST_R
  • INST_LUI
  • INST_AUIPC
  • INST_JAL
  • INST_JALR
  • INST_B
  • INST_FENCE
  • INST_SYS
  • INST_L/INST_FL
  • INST_S/INST_FS
  • INST_FMADD/INST_FMSUB/INST_FNMSUB/INST_FNMADD
  • INST_FCI
  • INST_GPU

これらの命令は、次の 6個に分類できます。

  • EX_ALU (EXT_F_ENABLEが1の時は、MUL/DIVもある)
  • EX_FPU (EXT_F_ENABLEが1の時)
  • EX_GPU
  • EX_CSR
  • EX_LSU

この6つに分離されたものが、VX_execute にて実行されます。

VX_issue

VX_issue の中には、下記の4つがインスタンスされています。

  • VX_ibuffer
  • VX_scoreboard
  • VX_gpr_stage
  • VX_dispatch

VX_decode からのデコード信号は、下記のように

  • VX_decode => VX_ibuffer => VX_dispatch

を経由して、VX_execute に流れていきます。

    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)
    );

下記のように対応しています。

  • alu_req_if <= EX_ALU
  • lsu_req_if <= EX_LSU
  • gpu_req_if <= EX_GPU
  • fpu_req_if <= EX_FPU
  • csr_req_if <= EX_CSR

VX_execute

VX_execute の中には、下記の6つがインスタンスされています。

  • VX_cache_arb
  • VX_alu_unit
  • VX_lsu_unit
  • VX_csr_unit
  • VX_fpu_unit
  • VX_gpu_unit

VX_cache_arb では、TEX/LSU Unit と D-Cache のアービタです。TEX は、EXT_TEX_ENABLEマクロが定義されている時有効です。

  • VX_alu_unit <= EX_ALU
  • VX_lsu_unit <= EX_LSU
  • VX_csr_unit <= EX_CSR
  • VX_fpu_unit <= EX_FPU
  • VX_gpu_unit <= EX_GPU

は、各処理を行うユニットです。

VX_commit

VX_commit では、VX_execute からの

  • alu_commit_if
  • ld_commit_if
  • st_commit_if
  • csr_commit_if
  • fpu_commit_if
  • gpu_commit_if

から

  • writeback_if
  • cmt_to_csr_if

を生成します。

module VX_commit #(
    parameter CORE_ID = 0
) (
    input wire              clk,
    input wire              reset,

    // inputs
    VX_commit_if.slave      alu_commit_if,
    VX_commit_if.slave      ld_commit_if,
    VX_commit_if.slave      st_commit_if, 
    VX_commit_if.slave      csr_commit_if,
`ifdef EXT_F_ENABLE
    VX_commit_if.slave      fpu_commit_if,
`endif
    VX_commit_if.slave      gpu_commit_if,

    // outputs
    VX_writeback_if.master  writeback_if,
    VX_cmt_to_csr_if.master cmt_to_csr_if
);

writeback_if は VX_issue に、cmt_to_csr_if は VX_execute に接続されています。

VX_issue の中では、VX_scoreboard と VX_gpr_stage に接続されています。

    VX_scoreboard #(
        .CORE_ID(CORE_ID)
    ) scoreboard (
        .clk        (clk),
        .reset      (scoreboard_reset),         
        .writeback_if(sboard_wb_if),
        .ibuffer_if (scoreboard_if)
    );

    VX_gpr_stage #(
        .CORE_ID(CORE_ID)
    ) gpr_stage (
        .clk          (clk),      
        .reset        (gpr_reset),          
        .writeback_if (writeback_if),
        .gpr_req_if   (gpr_req_if),
        .gpr_rsp_if   (gpr_rsp_if)
    );

VX_scoreboard は出力信号がありません。デッドロックのチェックをしているだけのようです。なので、シミュレーションにて活躍します。

VX_gpr_stage は、GPR (General Purpose Registers) の更新をしています。

cmt_to_csr は、VX_execute の中で、VX_csr_unit に接続されています。VX_csr_unit の中では VX_csr_data に接続されています。

VX_mem_unit

VX_mem_unit では、VX_pipeline からの I-Cache/D-Cache のインターフェースを受けて、Memory インターフェースとして出ていきます。

    VX_mem_unit #(
        .CORE_ID(CORE_ID)
    ) mem_unit (
        `SCOPE_BIND_VX_core_mem_unit
    `ifdef PERF_ENABLE
        .perf_memsys_if (perf_memsys_if),
    `endif

        .clk            (clk),
        .reset          (reset),

        // Core <-> Dcache
        .dcache_req_if  (dcache_req_if),
        .dcache_rsp_if  (dcache_rsp_if),
        
        // Core <-> Icache
        .icache_req_if  (icache_req_if),
        .icache_rsp_if  (icache_rsp_if),

        // Memory
        .mem_req_if     (mem_req_if),
        .mem_rsp_if     (mem_rsp_if)
    );

VX_mem_unit の中には、

  • VX_cache (I-Cache)
  • VX_cache (D-Cache)
  • VX_shared_mem + VX_smem_arb (SM_ENABLEマクロが定義されている場合)
  • VX_mem_arb

インスタンスされています。

  • VX_cache
  • VX_mem_arb

は、既に説明したものです。

おわりに

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