はじめに
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個に分類できます。
この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 では、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 からの
から
- 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 な部分を実装している部分をみていきます。