この記事は 半導体・ハードウェア開発 Advent Calendar 2017 - Qiita の5日目の記事です。
Advent-Calendarを埋めてくれるかた、今からでも募集中です!是非参加してください! 私一人では、クオリティのある記事を続けられそうにありません。。。(弱音)
(この記事は以前にオープンソースGPGPUを調査したときの記事の焼き直しです )
RISC-Vをはじめとする、オープンソースCPUが躍進している。 もともとオープンソースのCPUというのはOpenRISCをはじめとしていろいろ存在したが、オープンソースのGPUというのはほとんど存在していなかった。 (もともとGPGPU自体が歴史が浅いしね)。
オープンソースGPGPUの種類
私が見つけたのは以下の2種類だ。
- NyuziProcessor
https://github.com/jbush001/NyuziProcessor
命令セットも公開されており、テストプログラムも結構充実している。個人で開発しているようだが、完成度はかなり高いように感じる。 今でも積極的に開発が進んでいるようだ。
- MIAOW
こちらは大学発のオープンソースGPGPUのようだ。日本国内の国際学会COOLChipsでも発表がされている。
[https://github.com/VerticalResearchGroup/miaow:embed:cite]
[https://www.hotchips.org/wp-content/uploads/hc_archives/hc27/HC27.25-Tuesday-Epub/HC27.25.50-GPU-Epub/HC27.25.512-MIAOW-Balasubramaniam-UWisc-v1.2.pdf]
今回は、NyuziProcessorについて調査した。
NyuziProcessorの構成
NyuziProcessorは以下のような構成を取っており、メインメモリにアクセスするためのAXIバスと、I/Oを制御するためのPeripheral Busから構成されている。
NyuziProcessorのダウンロードとビルド
Ubuntuの場合、まずはパッケージをダウンロードする。
sudo apt-get -y install autoconf cmake make gcc g++ bison flex python \ python3 perl emacs openjdk-8-jdk swig zlib1g-dev python-dev \ libxml2-dev libedit-dev libncurses5-dev libsdl2-dev gtkwave imagemagick
パッケージのダウンロードとビルドを行う。
git clone https://github.com/jbush001/NyuziProcessor.git ./build/setup_tools.sh
テストを実行するためにはmake test
をタイプする。
make[1]: ディレクトリ '/home/msyksphinz/work/NyuziProcessor/tests' に入ります cd remote-gdb && python3 ./runtest.py gdb_breakpoint [PASS] gdb_remove_breakpoint [PASS] gdb_breakpoint_errors [PASS] gdb_single_step [PASS] gdb_single_step_breakpoint [PASS] gdb_read_write_memory [PASS] gdb_read_write_register [PASS] gdb_register_info [PASS] gdb_select_thread [PASS] gdb_thread_info [PASS] gdb_invalid_command [PASS] gdb_big_command [PASS] gdb_queries [PASS]
VivadoでNyuziProcessorを論理合成してみる
NyuziProcessorはALTERAのFPGAでインプリメントするようにできているが、論理合成までならXilinxのツールでも試行できる。
NyuziProcessorのリポジトリをForkして、Vivadoで論理合成する環境を構築する。
基本的には、Vivadoのスクリプトをそのまま流せばよい。hardware/fpga/de2-115/de2_115.qsf
を参考にして、ファイルリストを作成しておこう。
ちなみに、xdcのクロック定義は変えておかないとまずかったがそのままにしていたので、あまり厳密な結果ではない。。。
hardware/fpga/de2-115/de2_115.qsf
... set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top set_global_assignment -name VERILOG_FILE de2_115_top.sv set_global_assignment -name VERILOG_FILE ../common/vga_sequencer.sv set_global_assignment -name VERILOG_FILE ../common/vga_controller.sv set_global_assignment -name VERILOG_FILE ../common/sdram_controller.sv set_global_assignment -name VERILOG_FILE ../common/spi_controller.sv ...
hardware/fpga/vivado/filelist.tcl
../de2-115/de2_115_top.sv ../common/vga_sequencer.sv ../common/vga_controller.sv ...
cd hardware/fpga/vivado
make
合成結果は以下のようになった。合成ターゲットは 7z020clg484-1
(Xilinx ZYNQ)としている。
ZYNQでは入りきらないらしい。。。
+----------------------------+-------+-------+-----------+--------+ | Site Type | Used | Fixed | Available | Util% | +----------------------------+-------+-------+-----------+--------+ | Slice LUTs* | 84315 | 0 | 53200 | 158.49 | | LUT as Logic | 53182 | 0 | 53200 | 99.97 | | LUT as Memory | 31133 | 0 | 17400 | 178.93 | | LUT as Distributed RAM | 28892 | 0 | | | | LUT as Shift Register | 2241 | 0 | | | | Slice Registers | 43411 | 0 | 106400 | 40.80 | | Register as Flip Flop | 43411 | 0 | 106400 | 40.80 | | Register as Latch | 0 | 0 | 106400 | 0.00 | | F7 Muxes | 4058 | 0 | 26600 | 15.26 | | F8 Muxes | 1224 | 0 | 13300 | 9.20 | +----------------------------+-------+-------+-----------+--------+
NyuziProcessorのコア数はdefines.sv
で定義されている。
// // Configurable parameters // - Number of cache ways must be 1, 2, 4, or 8 (TLB_WAYS does not have // this constraint). This is a limitation in the cache_lru module. // - If you change the number of L2 ways, you must also modify the // flush_l2_cache function in testbench/verilator_tb.sv. Comments above // that function describe how and why. // - NUM_CORES must be 1-16. To synthesize more cores, increase the // width of core_id_t in defines.sv (as above, comments there describe why). // - The size of a cache is sets * ways * cache line size (64 bytes) // - L1D_SETS sets must be 64 or fewer (page size / cache line size) if // virtual address translation is enabled. This avoids aliasing in the // virtually indexed/physically tagged L1 cache by preventing the // same physical address from appearing in different cache sets // (see dcache_tag_stage) // `define NUM_CORES 1 `define THREADS_PER_CORE 4 `define L1D_WAYS 4 `define L1D_SETS 64 // 16k `define L1I_WAYS 4 `define L1I_SETS 64 // 16k `define L2_WAYS 8 `define L2_SETS 256 // 128k `define AXI_DATA_WIDTH 32 `define HAS_MMU 1 `define ITLB_ENTRIES 64 `define DTLB_ENTRIES 64 `define TLB_WAYS 4
NUM_CORES
を4に設定して再合成してみた。
まあ、こんな感じ。あまり詳細な解析までは進まなかった。。。
焼き直し前記事。